// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.

/// Defines the global environment for all type checking.
///
/// The environment (TcGlobals) are well-known types and values are hard-wired
/// into the compiler.  This lets the compiler perform particular optimizations
/// for these types and values, for example emitting optimized calls for
/// comparison and hashing functions.
module internal FSharp.Compiler.TcGlobals

open System.Collections.Concurrent
#if !FABLE_COMPILER
open System.Linq
#endif
open System.Diagnostics

open Internal.Utilities.Library
open Internal.Utilities.Library.Extras
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.CompilerGlobalState
open FSharp.Compiler.Features
open FSharp.Compiler.IO
open FSharp.Compiler.Syntax.PrettyNaming
open FSharp.Compiler.Text.FileIndex
open FSharp.Compiler.Text.Range
open FSharp.Compiler.TypedTree
open FSharp.Compiler.TypedTreeBasics
open Internal.Utilities

let internal DummyFileNameForRangesWithoutASpecificLocation = startupFileName
let private envRange = rangeN DummyFileNameForRangesWithoutASpecificLocation 0

/// Represents an intrinsic value from FSharp.Core known to the compiler
[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
type IntrinsicValRef =
    | IntrinsicValRef of NonLocalEntityRef * string * bool * TType * ValLinkageFullKey

    member x.Name = (let (IntrinsicValRef(_, nm, _,  _, _)) = x in nm)

    /// For debugging
    [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
    member x.DebugText = x.ToString()

    /// For debugging
    override x.ToString() = x.Name

let ValRefForIntrinsic (IntrinsicValRef(mvr, _, _, _, key))  = mkNonLocalValRef mvr key

//-------------------------------------------------------------------------
// Access the initial environment: names
//-------------------------------------------------------------------------

[<AutoOpen>]
module FSharpLib =

    let Root                       = "Microsoft.FSharp"
    let RootPath                   = splitNamespace Root
    let Core                       = Root + ".Core"
    let CorePath                   = splitNamespace Core
    let CoreOperatorsCheckedName   = Root + ".Core.Operators.Checked"
    let ControlName                = Root + ".Control"
    let LinqName                   = Root + ".Linq"
    let CollectionsName            = Root + ".Collections"
    let LanguagePrimitivesName     = Root + ".Core.LanguagePrimitives"
    let CompilerServicesName       = Root + ".Core.CompilerServices"
    let LinqRuntimeHelpersName     = Root + ".Linq.RuntimeHelpers"
    let ExtraTopLevelOperatorsName = Root + ".Core.ExtraTopLevelOperators"
    let NativeInteropName          = Root + ".NativeInterop"

    let QuotationsName             = Root + ".Quotations"

    let ControlPath                = splitNamespace ControlName
    let LinqPath                   = splitNamespace LinqName
    let CollectionsPath            = splitNamespace CollectionsName
    let NativeInteropPath          = splitNamespace NativeInteropName |> Array.ofList
    let CompilerServicesPath       = splitNamespace CompilerServicesName |> Array.ofList
    let LinqRuntimeHelpersPath     = splitNamespace LinqRuntimeHelpersName |> Array.ofList
    let QuotationsPath             = splitNamespace QuotationsName |> Array.ofList

    let RootPathArray              = RootPath |> Array.ofList
    let CorePathArray              = CorePath |> Array.ofList
    let LinqPathArray              = LinqPath |> Array.ofList
    let ControlPathArray           = ControlPath |> Array.ofList
    let CollectionsPathArray       = CollectionsPath |> Array.ofList

//-------------------------------------------------------------------------
// Access the initial environment: helpers to build references
//-------------------------------------------------------------------------

type
    [<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
    BuiltinAttribInfo =
    | AttribInfo of ILTypeRef * TyconRef

    member this.TyconRef = let (AttribInfo(_, tcref)) = this in tcref

    member this.TypeRef  = let (AttribInfo(tref, _)) = this in tref

    /// For debugging
    [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
    member x.DebugText = x.ToString()

    /// For debugging
    override x.ToString() = x.TyconRef.ToString()


[<Literal>]
let tname_InternalsVisibleToAttribute = "System.Runtime.CompilerServices.InternalsVisibleToAttribute"
[<Literal>]
let tname_DebuggerNonUserCodeAttribute = "System.Diagnostics.DebuggerNonUserCodeAttribute"
[<Literal>]
let tname_DebuggableAttribute_DebuggingModes = "DebuggingModes"
[<Literal>]
let tname_DebuggerHiddenAttribute = "System.Diagnostics.DebuggerHiddenAttribute"
[<Literal>]
let tname_DebuggerDisplayAttribute = "System.Diagnostics.DebuggerDisplayAttribute"
[<Literal>]
let tname_DebuggerTypeProxyAttribute = "System.Diagnostics.DebuggerTypeProxyAttribute"
[<Literal>]
let tname_DebuggerStepThroughAttribute = "System.Diagnostics.DebuggerStepThroughAttribute"
[<Literal>]
let tname_DebuggerBrowsableAttribute = "System.Diagnostics.DebuggerBrowsableAttribute"
[<Literal>]
let tname_DebuggerBrowsableState = "System.Diagnostics.DebuggerBrowsableState"

[<Literal>]
let tname_StringBuilder = "System.Text.StringBuilder"
[<Literal>]
let tname_IComparable = "System.IComparable"
[<Literal>]
let tname_Exception = "System.Exception"
[<Literal>]
let tname_Missing = "System.Reflection.Missing"
[<Literal>]
let tname_FormattableString = "System.FormattableString"
[<Literal>]
let tname_SerializationInfo = "System.Runtime.Serialization.SerializationInfo"
[<Literal>]
let tname_StreamingContext = "System.Runtime.Serialization.StreamingContext"
[<Literal>]
let tname_SecurityPermissionAttribute = "System.Security.Permissions.SecurityPermissionAttribute"
[<Literal>]
let tname_Delegate = "System.Delegate"
[<Literal>]
let tname_ValueType = "System.ValueType"
[<Literal>]
let tname_Enum = "System.Enum"
[<Literal>]
let tname_FlagsAttribute = "System.FlagsAttribute"
[<Literal>]
let tname_Array = "System.Array"
[<Literal>]
let tname_RuntimeArgumentHandle = "System.RuntimeArgumentHandle"
[<Literal>]
let tname_RuntimeTypeHandle = "System.RuntimeTypeHandle"
[<Literal>]
let tname_RuntimeMethodHandle = "System.RuntimeMethodHandle"
[<Literal>]
let tname_RuntimeFieldHandle = "System.RuntimeFieldHandle"
[<Literal>]
let tname_CompilerGeneratedAttribute = "System.Runtime.CompilerServices.CompilerGeneratedAttribute"
[<Literal>]
let tname_ReferenceAssemblyAttribute = "System.Runtime.CompilerServices.ReferenceAssemblyAttribute"
[<Literal>]
let tname_UnmanagedType = "System.Runtime.InteropServices.UnmanagedType"
[<Literal>]
let tname_DebuggableAttribute = "System.Diagnostics.DebuggableAttribute"
[<Literal>]
let tname_AsyncCallback = "System.AsyncCallback"
[<Literal>]
let tname_IAsyncResult = "System.IAsyncResult"
[<Literal>]
let tname_IsByRefLikeAttribute = "System.Runtime.CompilerServices.IsByRefLikeAttribute"


//-------------------------------------------------------------------------
// Table of all these "globals"
//-------------------------------------------------------------------------

[<RequireQualifiedAccess>]
type CompilationMode =
    | Unset
    | OneOff
    | Service
    | Interactive

type TcGlobals(
    compilingFSharpCore: bool,
    ilg: ILGlobals,
    fslibCcu: CcuThunk,
    directoryToResolveRelativePaths,
    mlCompatibility: bool,
    isInteractive: bool,
    checkNullness: bool,
    useReflectionFreeCodeGen: bool,
    // The helper to find system types amongst referenced DLLs
    tryFindSysTypeCcuHelper: string list -> string -> bool -> CcuThunk option,
    emitDebugInfoInQuotations: bool,
    noDebugAttributes: bool,
    pathMap: PathMap,
    langVersion: LanguageVersion,
    realsig: bool,
    compilationMode: CompilationMode) =

  let v_langFeatureNullness = langVersion.SupportsFeature LanguageFeature.NullnessChecking

  let v_knownWithNull =
      if v_langFeatureNullness then KnownWithNull else KnownAmbivalentToNull

  let v_knownWithoutNull =
      if v_langFeatureNullness then KnownWithoutNull else KnownAmbivalentToNull

  let mkNonGenericTy tcref = TType_app(tcref, [], v_knownWithoutNull)

  let mkNonGenericTyWithNullness tcref nullness = TType_app(tcref, [], nullness)

  let mkNonLocalTyconRef2 ccu path n = mkNonLocalTyconRef (mkNonLocalEntityRef ccu path) n

  let mk_MFCore_tcref             ccu n = mkNonLocalTyconRef2 ccu CorePathArray n
  let mk_MFQuotations_tcref       ccu n = mkNonLocalTyconRef2 ccu QuotationsPath n
  let mk_MFLinq_tcref             ccu n = mkNonLocalTyconRef2 ccu LinqPathArray n
  let mk_MFCollections_tcref      ccu n = mkNonLocalTyconRef2 ccu CollectionsPathArray n
  let mk_MFCompilerServices_tcref ccu n = mkNonLocalTyconRef2 ccu CompilerServicesPath n
  let mk_MFControl_tcref          ccu n = mkNonLocalTyconRef2 ccu ControlPathArray n

  let tryFindSysTypeCcu path nm = tryFindSysTypeCcuHelper path nm false

  let tryFindPublicSysTypeCcu path nm = tryFindSysTypeCcuHelper path nm true

  let vara = Construct.NewRigidTypar "a" envRange
  let varb = Construct.NewRigidTypar "b" envRange
  let varc = Construct.NewRigidTypar "c" envRange
  let vard = Construct.NewRigidTypar "d" envRange
  let vare = Construct.NewRigidTypar "e" envRange

  let varaTy = mkTyparTy vara
  let varbTy = mkTyparTy varb
  let varcTy = mkTyparTy varc
  let vardTy = mkTyparTy vard
  let vareTy = mkTyparTy vare

  let v_int_tcr        = mk_MFCore_tcref fslibCcu "int"
  let v_nativeint_tcr  = mk_MFCore_tcref fslibCcu "nativeint"
  let v_unativeint_tcr = mk_MFCore_tcref fslibCcu "unativeint"
  let v_int32_tcr      = mk_MFCore_tcref fslibCcu "int32"
  let v_int16_tcr      = mk_MFCore_tcref fslibCcu "int16"
  let v_int64_tcr      = mk_MFCore_tcref fslibCcu "int64"
  let v_uint16_tcr     = mk_MFCore_tcref fslibCcu "uint16"
  let v_uint32_tcr     = mk_MFCore_tcref fslibCcu "uint32"
  let v_uint64_tcr     = mk_MFCore_tcref fslibCcu "uint64"
  let v_sbyte_tcr      = mk_MFCore_tcref fslibCcu "sbyte"
  let v_decimal_tcr    = mk_MFCore_tcref fslibCcu "decimal"
  let v_pdecimal_tcr   = mk_MFCore_tcref fslibCcu "decimal`1"
  let v_byte_tcr       = mk_MFCore_tcref fslibCcu "byte"
  let v_bool_tcr       = mk_MFCore_tcref fslibCcu "bool"
  let v_string_tcr     = mk_MFCore_tcref fslibCcu "string"
  let v_obj_tcr        = mk_MFCore_tcref fslibCcu "obj"
  let v_unit_tcr_canon = mk_MFCore_tcref fslibCcu "Unit"
  let v_unit_tcr_nice  = mk_MFCore_tcref fslibCcu "unit"
  let v_exn_tcr        = mk_MFCore_tcref fslibCcu "exn"
  let v_char_tcr       = mk_MFCore_tcref fslibCcu "char"
  let v_float_tcr      = mk_MFCore_tcref fslibCcu "float"
  let v_float32_tcr    = mk_MFCore_tcref fslibCcu "float32"
  let v_pfloat_tcr      = mk_MFCore_tcref fslibCcu "float`1"
  let v_pfloat32_tcr    = mk_MFCore_tcref fslibCcu "float32`1"
  let v_pint_tcr        = mk_MFCore_tcref fslibCcu "int`1"
  let v_pint8_tcr       = mk_MFCore_tcref fslibCcu "sbyte`1"
  let v_pint16_tcr      = mk_MFCore_tcref fslibCcu "int16`1"
  let v_pint64_tcr      = mk_MFCore_tcref fslibCcu "int64`1"
  let v_pnativeint_tcr  = mk_MFCore_tcref fslibCcu "nativeint`1"
  let v_puint_tcr       = mk_MFCore_tcref fslibCcu "uint`1"
  let v_puint8_tcr      = mk_MFCore_tcref fslibCcu "byte`1"
  let v_puint16_tcr     = mk_MFCore_tcref fslibCcu "uint16`1"
  let v_puint64_tcr     = mk_MFCore_tcref fslibCcu "uint64`1"
  let v_punativeint_tcr = mk_MFCore_tcref fslibCcu "unativeint`1"
  let v_byref_tcr       = mk_MFCore_tcref fslibCcu "byref`1"
  let v_byref2_tcr      = mk_MFCore_tcref fslibCcu "byref`2"
  let v_outref_tcr      = mk_MFCore_tcref fslibCcu "outref`1"
  let v_inref_tcr       = mk_MFCore_tcref fslibCcu "inref`1"
  let v_nativeptr_tcr   = mk_MFCore_tcref fslibCcu "nativeptr`1"
  let v_voidptr_tcr     = mk_MFCore_tcref fslibCcu "voidptr"
  let v_ilsigptr_tcr    = mk_MFCore_tcref fslibCcu "ilsigptr`1"
  let v_fastFunc_tcr    = mk_MFCore_tcref fslibCcu "FSharpFunc`2"
  let v_refcell_tcr_canon = mk_MFCore_tcref fslibCcu "Ref`1"
  let v_refcell_tcr_nice  = mk_MFCore_tcref fslibCcu "ref`1"
  let v_mfe_tcr           = mk_MFCore_tcref fslibCcu "MatchFailureException"

  let mutable embeddedILTypeDefs = ConcurrentDictionary<string, ILTypeDef>()

  let dummyAssemblyNameCarryingUsefulErrorInformation path typeName =
      FSComp.SR.tcGlobalsSystemTypeNotFound (String.concat "." path + "." + typeName)

  // Search for a type. If it is not found, leave a dangling CCU reference with some useful diagnostic information should
  // the type actually be dereferenced
  let findSysTypeCcu path typeName =
      match tryFindSysTypeCcu path typeName with
      | None -> CcuThunk.CreateDelayed(dummyAssemblyNameCarryingUsefulErrorInformation path typeName)
      | Some ccu -> ccu

  let tryFindSysTyconRef path nm =
      match tryFindSysTypeCcu path nm with
      | Some ccu -> Some (mkNonLocalTyconRef2 ccu (Array.ofList path) nm)
      | None -> None

  let findSysTyconRef path nm =
      let ccu = findSysTypeCcu path nm
      mkNonLocalTyconRef2 ccu (Array.ofList path) nm

  let findSysILTypeRef nm =
      let path, typeName = splitILTypeName nm
      let scoref =
          match tryFindSysTypeCcu path typeName with
          | None -> ILScopeRef.Assembly (mkSimpleAssemblyRef (dummyAssemblyNameCarryingUsefulErrorInformation path typeName))
          | Some ccu -> ccu.ILScopeRef
      mkILTyRef (scoref, nm)

  let tryFindSysILTypeRef nm =
      let path, typeName = splitILTypeName nm
      tryFindSysTypeCcu path typeName |> Option.map (fun ccu -> mkILTyRef (ccu.ILScopeRef, nm))

  let findSysAttrib nm =
      let tref = findSysILTypeRef nm
      let path, typeName = splitILTypeName nm
      AttribInfo(tref, findSysTyconRef path typeName)

  let tryFindSysAttrib nm =
      let path, typeName = splitILTypeName nm

      // System Attributes must be public types.
      match tryFindSysTypeCcu path typeName with
      | Some _ -> Some (findSysAttrib nm)
      | None -> None

  let findPublicSysAttrib nm =
      let path, typeName = splitILTypeName nm
      let scoref, ccu =
            match tryFindPublicSysTypeCcu path typeName with
            | None ->
                ILScopeRef.Assembly (mkSimpleAssemblyRef (dummyAssemblyNameCarryingUsefulErrorInformation path typeName)),
                CcuThunk.CreateDelayed(dummyAssemblyNameCarryingUsefulErrorInformation path typeName)
            | Some ccu ->
                ccu.ILScopeRef,
                ccu
      let tref = mkILTyRef (scoref, nm)
      let tcref = mkNonLocalTyconRef2 ccu (Array.ofList path) typeName
      AttribInfo(tref, tcref)

  // Well known set of generated embeddable attribute names
  static let isInEmbeddableKnownSet name =
      match name with
      | "System.Runtime.CompilerServices.IsReadOnlyAttribute"
      | "System.Runtime.CompilerServices.IsUnmanagedAttribute"
      | "System.Runtime.CompilerServices.NullableAttribute"
      | "System.Runtime.CompilerServices.NullableContextAttribute"
      | "System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute"
      | "System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute"
      | "System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes" -> true
      | _ -> false

  let findOrEmbedSysPublicType nm =

      assert (isInEmbeddableKnownSet nm)                        //Ensure that the named type is in known set of embedded types

      let sysAttrib = findPublicSysAttrib nm
      if sysAttrib.TyconRef.CanDeref then
          sysAttrib
      else
          let attrRef = ILTypeRef.Create(ILScopeRef.Local, [], nm)
          let attrTycon =
             Construct.NewTycon(
                 Some (CompPath(ILScopeRef.Local, SyntaxAccess.Internal, [])),
                 attrRef.Name,
                 range0,
                 taccessInternal,
                  taccessInternal,
                  TyparKind.Type,
                  LazyWithContext.NotLazy [],
                  FSharp.Compiler.Xml.XmlDoc.Empty,
                  false,
                  false,
                  false,
                  MaybeLazy.Strict(Construct.NewEmptyModuleOrNamespaceType ModuleOrType)
              )
          AttribInfo(attrRef, mkLocalTyconRef attrTycon)

  let mkSysNonGenericTy path n = mkNonGenericTy(findSysTyconRef path n)
  let tryMkSysNonGenericTy path n = tryFindSysTyconRef path n |> Option.map mkNonGenericTy

  let sys = ["System"]
  let sysCollections = ["System";"Collections"]
  let sysGenerics = ["System";"Collections";"Generic"]
  let sysCompilerServices = ["System";"Runtime";"CompilerServices"]

  let lazy_tcr = findSysTyconRef sys "Lazy`1"
  let v_fslib_IEvent2_tcr        = mk_MFControl_tcref fslibCcu "IEvent`2"
  let v_tcref_IObservable      = findSysTyconRef sys "IObservable`1"
  let v_tcref_IObserver        = findSysTyconRef sys "IObserver`1"
  let v_fslib_IDelegateEvent_tcr = mk_MFControl_tcref fslibCcu "IDelegateEvent`1"

  let v_option_tcr_nice     = mk_MFCore_tcref fslibCcu "option`1"
  let v_valueoption_tcr_nice = mk_MFCore_tcref fslibCcu "voption`1"
  let v_list_tcr_canon        = mk_MFCollections_tcref fslibCcu "List`1"
  let v_list_tcr_nice            = mk_MFCollections_tcref fslibCcu "list`1"
  let v_lazy_tcr_nice            = mk_MFControl_tcref fslibCcu "Lazy`1"
  let v_seq_tcr                  = mk_MFCollections_tcref fslibCcu "seq`1"
  let v_format_tcr               = mk_MFCore_tcref     fslibCcu "PrintfFormat`5"
  let v_format4_tcr              = mk_MFCore_tcref     fslibCcu "PrintfFormat`4"
  let v_date_tcr                 = findSysTyconRef sys "DateTime"
  let v_IEnumerable_tcr          = findSysTyconRef sysGenerics "IEnumerable`1"
  let v_IEnumerator_tcr          = findSysTyconRef sysGenerics "IEnumerator`1"
  let v_System_Attribute_tcr     = findSysTyconRef sys "Attribute"
  let v_expr_tcr                 = mk_MFQuotations_tcref fslibCcu "Expr`1"
  let v_raw_expr_tcr             = mk_MFQuotations_tcref fslibCcu "Expr"
  let v_query_builder_tcref         = mk_MFLinq_tcref fslibCcu "QueryBuilder"
  let v_querySource_tcr         = mk_MFLinq_tcref fslibCcu "QuerySource`2"
  let v_linqExpression_tcr     = findSysTyconRef ["System";"Linq";"Expressions"] "Expression`1"

  let v_il_arr_tcr_map =
      Array.init 32 (fun idx ->
          let type_sig =
              let rank = idx + 1
              if rank = 1 then "[]`1"
              else "[" + (String.replicate (rank - 1) ",") + "]`1"
          mk_MFCore_tcref fslibCcu type_sig)

  let v_byte_ty         = mkNonGenericTy v_byte_tcr
  let v_sbyte_ty        = mkNonGenericTy v_sbyte_tcr
  let v_int16_ty        = mkNonGenericTy v_int16_tcr
  let v_uint16_ty       = mkNonGenericTy v_uint16_tcr
  let v_int_ty          = mkNonGenericTy v_int_tcr
  let v_int32_ty        = mkNonGenericTy v_int32_tcr
  let v_uint32_ty       = mkNonGenericTy v_uint32_tcr
  let v_int64_ty        = mkNonGenericTy v_int64_tcr
  let v_uint64_ty       = mkNonGenericTy v_uint64_tcr
  let v_float32_ty      = mkNonGenericTy v_float32_tcr
  let v_float_ty        = mkNonGenericTy v_float_tcr
  let v_nativeint_ty    = mkNonGenericTy v_nativeint_tcr
  let v_unativeint_ty   = mkNonGenericTy v_unativeint_tcr

  let v_enum_ty         = mkNonGenericTy v_int_tcr
  let v_bool_ty         = mkNonGenericTy v_bool_tcr
  let v_char_ty         = mkNonGenericTy v_char_tcr
  let v_obj_ty_without_null = mkNonGenericTyWithNullness v_obj_tcr v_knownWithoutNull
  let v_obj_ty_ambivalent = mkNonGenericTyWithNullness v_obj_tcr KnownAmbivalentToNull
  let v_obj_ty_with_null    = mkNonGenericTyWithNullness v_obj_tcr v_knownWithNull
  let v_IFormattable_tcref = findSysTyconRef sys "IFormattable"
  let v_FormattableString_tcref = findSysTyconRef sys "FormattableString"
  let v_IFormattable_ty = mkNonGenericTy v_IFormattable_tcref
  let v_FormattableString_ty = mkNonGenericTy v_FormattableString_tcref
  let v_FormattableStringFactory_tcref = findSysTyconRef sysCompilerServices "FormattableStringFactory"
  let v_FormattableStringFactory_ty = mkNonGenericTy v_FormattableStringFactory_tcref
  let v_string_ty       = mkNonGenericTy v_string_tcr
  let v_string_ty_ambivalent = mkNonGenericTyWithNullness v_string_tcr KnownAmbivalentToNull
  let v_decimal_ty      = mkSysNonGenericTy sys "Decimal"
  let v_unit_ty         = mkNonGenericTy v_unit_tcr_nice
  let v_system_Type_ty = mkSysNonGenericTy sys "Type"
  let v_Array_tcref = findSysTyconRef sys "Array"

  let v_system_Reflection_MethodInfo_ty = mkSysNonGenericTy ["System";"Reflection"] "MethodInfo"
  let v_nullable_tcr = findSysTyconRef sys "Nullable`1"
  (* local helpers to build value infos *)
  let mkNullableTy ty = TType_app(v_nullable_tcr, [ty], v_knownWithoutNull)
  let mkByrefTy ty = TType_app(v_byref_tcr, [ty], v_knownWithoutNull)
  let mkNativePtrTy ty = TType_app(v_nativeptr_tcr, [ty], v_knownWithoutNull)
  let mkFunTy d r = TType_fun (d, r, v_knownWithoutNull)
  let mkFunTyWithNullness d r nullness = TType_fun (d, r, nullness)
  let (-->) d r = mkFunTy d r
  let mkIteratedFunTy dl r = List.foldBack mkFunTy dl r
  let mkSmallRefTupledTy l = match l with [] -> v_unit_ty | [h] -> h | tys -> mkRawRefTupleTy tys
  let mkForallTyIfNeeded d r = match d with [] -> r | tps -> TType_forall(tps, r)

      // A table of all intrinsics that the compiler cares about
  let v_knownIntrinsics = ConcurrentDictionary<string * string option * string * int, ValRef>(HashIdentity.Structural)

  let makeIntrinsicValRefGeneral isKnown (enclosingEntity, logicalName, memberParentName, compiledNameOpt, typars, (argTys, retTy))  =
      let ty = mkForallTyIfNeeded typars (mkIteratedFunTy (List.map mkSmallRefTupledTy argTys) retTy)
      let isMember = Option.isSome memberParentName
      let argCount = if isMember then List.sumBy List.length argTys else 0
      let linkageType = if isMember then Some ty else None
      let key = ValLinkageFullKey({ MemberParentMangledName=memberParentName; MemberIsOverride=false; LogicalName=logicalName; TotalArgCount= argCount }, linkageType)
      let vref = IntrinsicValRef(enclosingEntity, logicalName, isMember, ty, key)
      let compiledName = defaultArg compiledNameOpt logicalName

      let key = (enclosingEntity.LastItemMangledName, memberParentName, compiledName, argCount)
      assert not (v_knownIntrinsics.ContainsKey(key))
      if isKnown && not (v_knownIntrinsics.ContainsKey(key)) then
          v_knownIntrinsics[key] <- ValRefForIntrinsic vref
      vref

  let makeIntrinsicValRef info = makeIntrinsicValRefGeneral true info
  let makeOtherIntrinsicValRef info = makeIntrinsicValRefGeneral false info

  let v_IComparer_ty = mkSysNonGenericTy sysCollections "IComparer"
  let v_IEqualityComparer_ty = mkSysNonGenericTy sysCollections "IEqualityComparer"

  let v_system_RuntimeMethodHandle_ty = mkSysNonGenericTy sys "RuntimeMethodHandle"

  let mk_unop_ty ty             = [[ty]], ty
  let mk_binop_ty ty            = [[ty]; [ty]], ty
  let mk_shiftop_ty ty          = [[ty]; [v_int_ty]], ty
  let mk_binop_ty3 ty1 ty2 ty3  = [[ty1]; [ty2]], ty3
  let mk_rel_sig ty             = [[ty];[ty]], v_bool_ty
  let mk_compare_sig ty         = [[ty];[ty]], v_int_ty
  let mk_hash_sig ty            = [[ty]], v_int_ty
  let mk_compare_withc_sig  ty = [[v_IComparer_ty];[ty]; [ty]], v_int_ty
  let mk_equality_withc_sig ty = [[v_IEqualityComparer_ty];[ty];[ty]], v_bool_ty
  let mk_hash_withc_sig     ty = [[v_IEqualityComparer_ty]; [ty]], v_int_ty

  let mkListTy ty = TType_app(v_list_tcr_nice, [ty], v_knownWithoutNull)

  let mkSeqTy ty1 = TType_app(v_seq_tcr, [ty1], v_knownWithoutNull)

  let mkIEvent2Ty ty1 ty2 = TType_app (v_fslib_IEvent2_tcr, [ty1; ty2], v_knownWithoutNull)

  let mkRefCellTy ty = TType_app(v_refcell_tcr_canon, [ty], v_knownWithoutNull)

  let mkOptionTy ty = TType_app(v_option_tcr_nice, [ty], v_knownWithoutNull)

  let mkQuerySourceTy ty1 ty2 = TType_app(v_querySource_tcr, [ty1; ty2], v_knownWithoutNull)

  let v_tcref_System_Collections_IEnumerable = findSysTyconRef sysCollections "IEnumerable";

  let mkArrayType rank (ty : TType) : TType =
      assert (rank >= 1 && rank <= 32)
      TType_app(v_il_arr_tcr_map[rank - 1], [ty], v_knownWithoutNull)

  let mkLazyTy ty = TType_app(lazy_tcr, [ty], v_knownWithoutNull)

  let mkPrintfFormatTy aty bty cty dty ety = TType_app(v_format_tcr, [aty;bty;cty;dty; ety], v_knownWithoutNull)

  let mk_format4_ty aty bty cty dty = TType_app(v_format4_tcr, [aty;bty;cty;dty], v_knownWithoutNull)

  let mkQuotedExprTy aty = TType_app(v_expr_tcr, [aty], v_knownWithoutNull)

  let mkRawQuotedExprTy = TType_app(v_raw_expr_tcr, [], v_knownWithoutNull)

  let mkQueryBuilderTy = TType_app(v_query_builder_tcref, [], v_knownWithoutNull)

  let mkLinqExpressionTy aty = TType_app(v_linqExpression_tcr, [aty], v_knownWithoutNull)

  let v_cons_ucref = mkUnionCaseRef v_list_tcr_canon "op_ColonColon"

  let v_nil_ucref  = mkUnionCaseRef v_list_tcr_canon "op_Nil"

  let fslib_MF_nleref                   = mkNonLocalEntityRef fslibCcu RootPathArray
  let fslib_MFCore_nleref               = mkNonLocalEntityRef fslibCcu CorePathArray
  let fslib_MFLinq_nleref               = mkNonLocalEntityRef fslibCcu LinqPathArray
  let fslib_MFCollections_nleref        = mkNonLocalEntityRef fslibCcu CollectionsPathArray
  let fslib_MFCompilerServices_nleref   = mkNonLocalEntityRef fslibCcu CompilerServicesPath
  let fslib_MFLinqRuntimeHelpers_nleref = mkNonLocalEntityRef fslibCcu LinqRuntimeHelpersPath
  let fslib_MFControl_nleref            = mkNonLocalEntityRef fslibCcu ControlPathArray
  let fslib_MFNativeInterop_nleref      = mkNonLocalEntityRef fslibCcu NativeInteropPath

  let fslib_MFLanguagePrimitives_nleref        = mkNestedNonLocalEntityRef fslib_MFCore_nleref "LanguagePrimitives"
  let fslib_MFIntrinsicOperators_nleref        = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicOperators"
  let fslib_MFIntrinsicFunctions_nleref        = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicFunctions"
  let fslib_MFHashCompare_nleref               = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "HashCompare"
  let fslib_MFOperators_nleref                 = mkNestedNonLocalEntityRef fslib_MFCore_nleref "Operators"
  let fslib_MFByRefKinds_nleref                 = mkNestedNonLocalEntityRef fslib_MFCore_nleref "ByRefKinds"
  let fslib_MFOperatorIntrinsics_nleref        = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "OperatorIntrinsics"
  let fslib_MFOperatorsUnchecked_nleref        = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "Unchecked"
  let fslib_MFOperatorsChecked_nleref        = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "Checked"
  let fslib_MFExtraTopLevelOperators_nleref    = mkNestedNonLocalEntityRef fslib_MFCore_nleref "ExtraTopLevelOperators"
  let fslib_MFNullableOperators_nleref         = mkNestedNonLocalEntityRef fslib_MFLinq_nleref "NullableOperators"
  let fslib_MFQueryRunExtensions_nleref              = mkNestedNonLocalEntityRef fslib_MFLinq_nleref "QueryRunExtensions"
  let fslib_MFQueryRunExtensionsLowPriority_nleref   = mkNestedNonLocalEntityRef fslib_MFQueryRunExtensions_nleref "LowPriority"
  let fslib_MFQueryRunExtensionsHighPriority_nleref  = mkNestedNonLocalEntityRef fslib_MFQueryRunExtensions_nleref "HighPriority"

  let fslib_MFPrintfModule_nleref                 = mkNestedNonLocalEntityRef fslib_MFCore_nleref "PrintfModule"
  let fslib_MFSeqModule_nleref                 = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "SeqModule"
  let fslib_MFListModule_nleref                = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "ListModule"
  let fslib_MFArrayModule_nleref               = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "ArrayModule"
  let fslib_MFArray2DModule_nleref               = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "Array2DModule"
  let fslib_MFArray3DModule_nleref               = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "Array3DModule"
  let fslib_MFArray4DModule_nleref               = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "Array4DModule"
  let fslib_MFSetModule_nleref               = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "SetModule"
  let fslib_MFMapModule_nleref               = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "MapModule"
  let fslib_MFStringModule_nleref               = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "StringModule"
  let fslib_MFNativePtrModule_nleref               = mkNestedNonLocalEntityRef fslib_MFNativeInterop_nleref "NativePtrModule"
  let fslib_MFOptionModule_nleref              = mkNestedNonLocalEntityRef fslib_MFCore_nleref "OptionModule"
  let fslib_MFStateMachineHelpers_nleref            = mkNestedNonLocalEntityRef fslib_MFCompilerServices_nleref "StateMachineHelpers"
  let fslib_MFRuntimeHelpers_nleref            = mkNestedNonLocalEntityRef fslib_MFCompilerServices_nleref "RuntimeHelpers"
  let fslib_MFQuotations_nleref                = mkNestedNonLocalEntityRef fslib_MF_nleref "Quotations"

  let fslib_MFLinqRuntimeHelpersQuotationConverter_nleref        = mkNestedNonLocalEntityRef fslib_MFLinqRuntimeHelpers_nleref "LeafExpressionConverter"
  let fslib_MFLazyExtensions_nleref            = mkNestedNonLocalEntityRef fslib_MFControl_nleref "LazyExtensions"

  let v_ref_tuple1_tcr      = findSysTyconRef sys "Tuple`1"
  let v_ref_tuple2_tcr      = findSysTyconRef sys "Tuple`2"
  let v_ref_tuple3_tcr      = findSysTyconRef sys "Tuple`3"
  let v_ref_tuple4_tcr      = findSysTyconRef sys "Tuple`4"
  let v_ref_tuple5_tcr      = findSysTyconRef sys "Tuple`5"
  let v_ref_tuple6_tcr      = findSysTyconRef sys "Tuple`6"
  let v_ref_tuple7_tcr      = findSysTyconRef sys "Tuple`7"
  let v_ref_tuple8_tcr      = findSysTyconRef sys "Tuple`8"
  let v_struct_tuple1_tcr      = findSysTyconRef sys "ValueTuple`1"
  let v_struct_tuple2_tcr      = findSysTyconRef sys "ValueTuple`2"
  let v_struct_tuple3_tcr      = findSysTyconRef sys "ValueTuple`3"
  let v_struct_tuple4_tcr      = findSysTyconRef sys "ValueTuple`4"
  let v_struct_tuple5_tcr      = findSysTyconRef sys "ValueTuple`5"
  let v_struct_tuple6_tcr      = findSysTyconRef sys "ValueTuple`6"
  let v_struct_tuple7_tcr      = findSysTyconRef sys "ValueTuple`7"
  let v_struct_tuple8_tcr      = findSysTyconRef sys "ValueTuple`8"

  let v_choice2_tcr     = mk_MFCore_tcref fslibCcu "Choice`2"
  let v_choice3_tcr     = mk_MFCore_tcref fslibCcu "Choice`3"
  let v_choice4_tcr     = mk_MFCore_tcref fslibCcu "Choice`4"
  let v_choice5_tcr     = mk_MFCore_tcref fslibCcu "Choice`5"
  let v_choice6_tcr     = mk_MFCore_tcref fslibCcu "Choice`6"
  let v_choice7_tcr     = mk_MFCore_tcref fslibCcu "Choice`7"
  let tyconRefEq x y = primEntityRefEq compilingFSharpCore fslibCcu  x y

  let v_suppressed_types =
    [ mk_MFCore_tcref fslibCcu "Option`1";
      mk_MFCore_tcref fslibCcu "Ref`1";
      mk_MFCore_tcref fslibCcu "FSharpTypeFunc";
      mk_MFCore_tcref fslibCcu "FSharpFunc`2";
      mk_MFCore_tcref fslibCcu "Unit" ]

  let v_knownFSharpCoreModules =
     dict [ for nleref in [ fslib_MFLanguagePrimitives_nleref
                            fslib_MFIntrinsicOperators_nleref
                            fslib_MFIntrinsicFunctions_nleref
                            fslib_MFHashCompare_nleref
                            fslib_MFOperators_nleref
                            fslib_MFOperatorIntrinsics_nleref
                            fslib_MFOperatorsUnchecked_nleref
                            fslib_MFOperatorsChecked_nleref
                            fslib_MFExtraTopLevelOperators_nleref
                            fslib_MFNullableOperators_nleref
                            fslib_MFQueryRunExtensions_nleref
                            fslib_MFQueryRunExtensionsLowPriority_nleref
                            fslib_MFQueryRunExtensionsHighPriority_nleref

                            fslib_MFPrintfModule_nleref
                            fslib_MFSeqModule_nleref
                            fslib_MFListModule_nleref
                            fslib_MFArrayModule_nleref
                            fslib_MFArray2DModule_nleref
                            fslib_MFArray3DModule_nleref
                            fslib_MFArray4DModule_nleref
                            fslib_MFSetModule_nleref
                            fslib_MFMapModule_nleref
                            fslib_MFStringModule_nleref
                            fslib_MFNativePtrModule_nleref
                            fslib_MFOptionModule_nleref
                            fslib_MFStateMachineHelpers_nleref
                            fslib_MFRuntimeHelpers_nleref ] do

                    yield nleref.LastItemMangledName, ERefNonLocal nleref  ]

  let tryDecodeTupleTy tupInfo l =
      match l with
      | [t1;t2;t3;t4;t5;t6;t7;markerTy] ->
          match markerTy with
          | TType_app(tcref, [t8], _) when tyconRefEq tcref v_ref_tuple1_tcr -> mkRawRefTupleTy [t1;t2;t3;t4;t5;t6;t7;t8] |> Some
          | TType_app(tcref, [t8], _) when tyconRefEq tcref v_struct_tuple1_tcr -> mkRawStructTupleTy [t1;t2;t3;t4;t5;t6;t7;t8] |> Some
          | TType_tuple (_structness2, t8plus) -> TType_tuple (tupInfo, [t1;t2;t3;t4;t5;t6;t7] @ t8plus) |> Some
          | _ -> None
      | [] -> None
      | [_] -> None
      | _ -> TType_tuple (tupInfo, l)  |> Some

  let decodeTupleTyAndNullness tupInfo tinst _nullness =
      match tryDecodeTupleTy tupInfo tinst with
      | Some ty -> ty
      | None -> failwith "couldn't decode tuple ty"

  let decodeTupleTyAndNullnessIfPossible tcref tupInfo tinst nullness =
      match tryDecodeTupleTy tupInfo tinst with
      | Some ty -> ty
      | None -> TType_app(tcref, tinst, nullness)

  let decodeTupleTy tupInfo tinst =
      decodeTupleTyAndNullness tupInfo tinst v_knownWithoutNull

  let mk_MFCore_attrib nm : BuiltinAttribInfo =
      AttribInfo(mkILTyRef(ilg.fsharpCoreAssemblyScopeRef, Core + "." + nm), mk_MFCore_tcref fslibCcu nm)

  let mk_MFCompilerServices_attrib nm : BuiltinAttribInfo =
      AttribInfo(mkILTyRef(ilg.fsharpCoreAssemblyScopeRef, Core + "." + nm), mk_MFCompilerServices_tcref fslibCcu nm)

  let mkSourceDoc fileName = ILSourceDocument.Create(language=None, vendor=None, documentType=None, file=fileName)

  let compute i =
      let path = fileOfFileIndex i
      let fullPath = FileSystem.GetFullFilePathInDirectoryShim directoryToResolveRelativePaths path
      mkSourceDoc fullPath

  // Build the memoization table for files
  let v_memoize_file =
      MemoizationTable<int, ILSourceDocument>("v_memoize_file", compute, keyComparer = HashIdentity.Structural)

  let v_and_info =                   makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref,                    CompileOpName "&"                      , None                 , None          , [],         mk_rel_sig v_bool_ty)
  let v_addrof_info =                makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref,                    CompileOpName "~&"                     , None                 , None          , [vara],     ([[varaTy]], mkByrefTy varaTy))
  let v_addrof2_info =               makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref,                    CompileOpName "~&&"                    , None                 , None          , [vara],     ([[varaTy]], mkNativePtrTy varaTy))
  let v_and2_info =                  makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref,                    CompileOpName "&&"                     , None                 , None          , [],         mk_rel_sig v_bool_ty)
  let v_or_info =                    makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref,                    "or"                                   , None                 , Some "Or"     , [],         mk_rel_sig v_bool_ty)
  let v_or2_info =                   makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref,                    CompileOpName "||"                     , None                 , None          , [],         mk_rel_sig v_bool_ty)
  let v_compare_operator_info                = makeIntrinsicValRef(fslib_MFOperators_nleref,                   "compare"                              , None                 , Some "Compare", [vara],     mk_compare_sig varaTy)
  let v_equals_operator_info                 = makeIntrinsicValRef(fslib_MFOperators_nleref,                   CompileOpName "="                      , None                 , None          , [vara],     mk_rel_sig varaTy)
  let v_equals_nullable_operator_info        = makeIntrinsicValRef(fslib_MFNullableOperators_nleref,           CompileOpName "=?"                     , None                 , None          , [vara],     ([[varaTy];[mkNullableTy varaTy]], v_bool_ty))
  let v_nullable_equals_operator_info        = makeIntrinsicValRef(fslib_MFNullableOperators_nleref,           CompileOpName "?="                     , None                 , None          , [vara],     ([[mkNullableTy varaTy];[varaTy]], v_bool_ty))
  let v_nullable_equals_nullable_operator_info  = makeIntrinsicValRef(fslib_MFNullableOperators_nleref,        CompileOpName "?=?"                    , None                 , None          , [vara],     ([[mkNullableTy varaTy];[mkNullableTy varaTy]], v_bool_ty))
  let v_not_equals_operator_info             = makeIntrinsicValRef(fslib_MFOperators_nleref,                   CompileOpName "<>"                     , None                 , None          , [vara],     mk_rel_sig varaTy)
  let v_less_than_operator_info              = makeIntrinsicValRef(fslib_MFOperators_nleref,                   CompileOpName "<"                      , None                 , None          , [vara],     mk_rel_sig varaTy)
  let v_less_than_or_equals_operator_info    = makeIntrinsicValRef(fslib_MFOperators_nleref,                   CompileOpName "<="                     , None                 , None          , [vara],     mk_rel_sig varaTy)
  let v_greater_than_operator_info           = makeIntrinsicValRef(fslib_MFOperators_nleref,                   CompileOpName ">"                      , None                 , None          , [vara],     mk_rel_sig varaTy)
  let v_greater_than_or_equals_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref,                   CompileOpName ">="                     , None                 , None          , [vara],     mk_rel_sig varaTy)

  let v_enumOfValue_info                     = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref,          "EnumOfValue"                          , None                 , None          , [vara; varb],     ([[varaTy]], varbTy))

  let v_generic_comparison_withc_outer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref,           "GenericComparisonWithComparer"        , None                 , None          , [vara],     mk_compare_withc_sig  varaTy)
  let v_generic_hash_withc_tuple2_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastHashTuple2"                                   , None                 , None          , [vara;varb],               mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy]))
  let v_generic_hash_withc_tuple3_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastHashTuple3"                                   , None                 , None          , [vara;varb;varc],          mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy]))
  let v_generic_hash_withc_tuple4_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastHashTuple4"                                   , None                 , None          , [vara;varb;varc;vard],     mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy]))
  let v_generic_hash_withc_tuple5_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastHashTuple5"                                   , None                 , None          , [vara;varb;varc;vard;vare], mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy; vareTy]))
  let v_generic_equals_withc_tuple2_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastEqualsTuple2"                               , None                 , None          , [vara;varb],               mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy]))
  let v_generic_equals_withc_tuple3_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastEqualsTuple3"                               , None                 , None          , [vara;varb;varc],          mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy]))
  let v_generic_equals_withc_tuple4_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastEqualsTuple4"                               , None                 , None          , [vara;varb;varc;vard],     mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy]))
  let v_generic_equals_withc_tuple5_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastEqualsTuple5"                               , None                 , None          , [vara;varb;varc;vard;vare], mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy; vareTy]))

  let v_generic_compare_withc_tuple2_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastCompareTuple2"                             , None                 , None          , [vara;varb],               mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy]))
  let v_generic_compare_withc_tuple3_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastCompareTuple3"                             , None                 , None          , [vara;varb;varc],          mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy]))
  let v_generic_compare_withc_tuple4_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastCompareTuple4"                             , None                 , None          , [vara;varb;varc;vard],     mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy]))
  let v_generic_compare_withc_tuple5_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,           "FastCompareTuple5"                             , None                 , None          , [vara;varb;varc;vard;vare], mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy; vareTy]))


  let v_generic_equality_er_outer_info             = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref,    "GenericEqualityER"                    , None                 , None          , [vara],     mk_rel_sig varaTy)
  let v_get_generic_comparer_info               = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref,       "GenericComparer"                      , None                 , None          , [],         ([], v_IComparer_ty))
  let v_get_generic_er_equality_comparer_info      = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref,    "GenericEqualityERComparer"            , None                 , None          , [],         ([], v_IEqualityComparer_ty))
  let v_get_generic_per_equality_comparer_info  = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref,       "GenericEqualityComparer"              , None                 , None          , [],         ([], v_IEqualityComparer_ty))
  let v_generic_equality_withc_outer_info       = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref,       "GenericEqualityWithComparer"          , None                 , None          , [vara],     mk_equality_withc_sig varaTy)
  let v_generic_hash_withc_outer_info           = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref,       "GenericHashWithComparer"              , None                 , None          , [vara],     mk_hash_withc_sig varaTy)

  let v_generic_equality_er_inner_info         = makeIntrinsicValRef(fslib_MFHashCompare_nleref,               "GenericEqualityERIntrinsic"           , None                 , None          , [vara],     mk_rel_sig varaTy)
  let v_generic_equality_per_inner_info     = makeIntrinsicValRef(fslib_MFHashCompare_nleref,                  "GenericEqualityIntrinsic"             , None                 , None          , [vara],     mk_rel_sig varaTy)
  let v_generic_equality_withc_inner_info   = makeIntrinsicValRef(fslib_MFHashCompare_nleref,                  "GenericEqualityWithComparerIntrinsic" , None                 , None          , [vara],     mk_equality_withc_sig varaTy)
  let v_generic_comparison_inner_info       = makeIntrinsicValRef(fslib_MFHashCompare_nleref,                  "GenericComparisonIntrinsic"           , None                 , None          , [vara],     mk_compare_sig varaTy)
  let v_generic_comparison_withc_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,                  "GenericComparisonWithComparerIntrinsic", None                , None          , [vara],     mk_compare_withc_sig varaTy)

  let v_generic_hash_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,                              "GenericHashIntrinsic"                 , None                 , None          , [vara],     mk_hash_sig varaTy)
  let v_generic_hash_withc_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,                        "GenericHashWithComparerIntrinsic"     , None                 , None          , [vara],     mk_hash_withc_sig  varaTy)

  let v_create_instance_info       = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "CreateInstance"                       , None                 , None          , [vara],     ([[v_unit_ty]], varaTy))
  let v_unbox_info                 = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "UnboxGeneric"                         , None                 , None          , [vara],     ([[v_obj_ty_with_null]], varaTy))

  let v_unbox_fast_info            = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "UnboxFast"                            , None                 , None          , [vara],     ([[v_obj_ty_with_null]], varaTy))
  let v_istype_info                = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "TypeTestGeneric"                      , None                 , None          , [vara],     ([[v_obj_ty_with_null]], v_bool_ty))
  let v_istype_fast_info           = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "TypeTestFast"                         , None                 , None          , [vara],     ([[v_obj_ty_with_null]], v_bool_ty))

  let v_dispose_info               = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "Dispose"                              , None                 , None          , [vara],     ([[varaTy]], v_unit_ty))

  let v_getstring_info             = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "GetString"                            , None                 , None          , [],         ([[v_string_ty];[v_int_ty]], v_char_ty))

  let v_reference_equality_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref,                        "PhysicalEqualityIntrinsic"            , None                 , None          , [vara],     mk_rel_sig varaTy)

  let v_piperight_info             = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_PipeRight"                         , None                 , None          , [vara; varb],([[varaTy];[varaTy --> varbTy]], varbTy))
  let v_piperight2_info             = makeIntrinsicValRef(fslib_MFOperators_nleref,                            "op_PipeRight2"                        , None                 , None          , [vara; varb; varc],([[varaTy; varbTy];[varaTy --> (varbTy --> varcTy)]], varcTy))
  let v_piperight3_info             = makeIntrinsicValRef(fslib_MFOperators_nleref,                            "op_PipeRight3"                        , None                 , None          , [vara; varb; varc; vard],([[varaTy; varbTy; varcTy];[varaTy --> (varbTy --> (varcTy --> vardTy))]], vardTy))
  let v_bitwise_or_info            = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_BitwiseOr"                         , None                 , None          , [vara],     mk_binop_ty varaTy)
  let v_bitwise_and_info           = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_BitwiseAnd"                        , None                 , None          , [vara],     mk_binop_ty varaTy)
  let v_bitwise_xor_info           = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_ExclusiveOr"                       , None                 , None          , [vara],     mk_binop_ty varaTy)
  let v_bitwise_unary_not_info     = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_LogicalNot"                        , None                 , None          , [vara],     mk_unop_ty varaTy)
  let v_bitwise_shift_left_info    = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_LeftShift"                         , None                 , None          , [vara],     mk_shiftop_ty varaTy)
  let v_bitwise_shift_right_info   = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_RightShift"                        , None                 , None          , [vara],     mk_shiftop_ty varaTy)
  let v_exponentiation_info        = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_Exponentiation"                    , None                 , None          , [vara;varb],     ([[varaTy];[varbTy]], varaTy))
  let v_unchecked_addition_info    = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_Addition"                          , None                 , None          , [vara;varb;varc],     mk_binop_ty3 varaTy varbTy  varcTy)
  let v_unchecked_subtraction_info = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_Subtraction"                       , None                 , None          , [vara;varb;varc],     mk_binop_ty3 varaTy varbTy  varcTy)
  let v_unchecked_multiply_info    = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_Multiply"                          , None                 , None          , [vara;varb;varc],     mk_binop_ty3 varaTy varbTy  varcTy)
  let v_unchecked_division_info    = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_Division"                          , None                 , None          , [vara;varb;varc],     mk_binop_ty3 varaTy varbTy  varcTy)
  let v_unchecked_modulus_info     = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_Modulus"                           , None                 , None          , [vara;varb;varc],     mk_binop_ty3 varaTy varbTy  varcTy)
  let v_unchecked_unary_plus_info  = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_UnaryPlus"                         , None                 , None          , [vara],     mk_unop_ty varaTy)
  let v_unchecked_unary_minus_info = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_UnaryNegation"                     , None                 , None          , [vara],     mk_unop_ty varaTy)
  let v_unchecked_unary_not_info   = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "not"                                  , None                 , Some "Not"    , [],     mk_unop_ty v_bool_ty)
  let v_refcell_deref_info         = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_Dereference"                       , None                 , None          , [vara],     ([[mkRefCellTy varaTy]], varaTy))
  let v_refcell_assign_info        = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_ColonEquals"                       , None                 , None          , [vara],     ([[mkRefCellTy varaTy]; [varaTy]], v_unit_ty))
  let v_refcell_incr_info          = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "incr"                                 , None                 , Some "Increment" , [],     ([[mkRefCellTy v_int_ty]], v_unit_ty))
  let v_refcell_decr_info          = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "decr"                                 , None                 , Some "Decrement" , [],     ([[mkRefCellTy v_int_ty]], v_unit_ty))

  let v_checked_addition_info      = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "op_Addition"                          , None                 , None          , [vara;varb;varc],     mk_binop_ty3 varaTy varbTy  varcTy)
  let v_checked_subtraction_info   = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "op_Subtraction"                       , None                 , None          , [vara;varb;varc],     mk_binop_ty3 varaTy varbTy  varcTy)
  let v_checked_multiply_info      = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "op_Multiply"                          , None                 , None          , [vara;varb;varc],     mk_binop_ty3 varaTy varbTy  varcTy)
  let v_checked_unary_minus_info   = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "op_UnaryNegation"                     , None                 , None          , [vara],     mk_unop_ty varaTy)

  let v_byte_checked_info          = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "byte"                                 , None                 , Some "ToByte",    [vara],   ([[varaTy]], v_byte_ty))
  let v_sbyte_checked_info         = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "sbyte"                                , None                 , Some "ToSByte",   [vara],   ([[varaTy]], v_sbyte_ty))
  let v_int16_checked_info         = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "int16"                                , None                 , Some "ToInt16",   [vara],   ([[varaTy]], v_int16_ty))
  let v_uint16_checked_info        = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "uint16"                               , None                 , Some "ToUInt16",  [vara],   ([[varaTy]], v_uint16_ty))
  let v_int_checked_info           = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "int"                                  , None                 , Some "ToInt",     [vara],   ([[varaTy]], v_int_ty))
  let v_int32_checked_info         = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "int32"                                , None                 , Some "ToInt32",   [vara],   ([[varaTy]], v_int32_ty))
  let v_uint32_checked_info        = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "uint32"                               , None                 , Some "ToUInt32",  [vara],   ([[varaTy]], v_uint32_ty))
  let v_int64_checked_info         = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "int64"                                , None                 , Some "ToInt64",   [vara],   ([[varaTy]], v_int64_ty))
  let v_uint64_checked_info        = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "uint64"                               , None                 , Some "ToUInt64",  [vara],   ([[varaTy]], v_uint64_ty))
  let v_nativeint_checked_info     = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "nativeint"                            , None                 , Some "ToIntPtr",  [vara],   ([[varaTy]], v_nativeint_ty))
  let v_unativeint_checked_info    = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref,                      "unativeint"                           , None                 , Some "ToUIntPtr", [vara],   ([[varaTy]], v_unativeint_ty))

  let v_byte_operator_info         = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "byte"                                 , None                 , Some "ToByte",    [vara],   ([[varaTy]], v_byte_ty))
  let v_sbyte_operator_info        = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "sbyte"                                , None                 , Some "ToSByte",   [vara],   ([[varaTy]], v_sbyte_ty))
  let v_int16_operator_info        = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "int16"                                , None                 , Some "ToInt16",   [vara],   ([[varaTy]], v_int16_ty))
  let v_uint16_operator_info       = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "uint16"                               , None                 , Some "ToUInt16",  [vara],   ([[varaTy]], v_uint16_ty))
  let v_int32_operator_info        = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "int32"                                , None                 , Some "ToInt32",   [vara],   ([[varaTy]], v_int32_ty))
  let v_uint32_operator_info       = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "uint32"                               , None                 , Some "ToUInt32",  [vara],   ([[varaTy]], v_uint32_ty))
  let v_int64_operator_info        = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "int64"                                , None                 , Some "ToInt64",   [vara],   ([[varaTy]], v_int64_ty))
  let v_uint64_operator_info       = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "uint64"                               , None                 , Some "ToUInt64",  [vara],   ([[varaTy]], v_uint64_ty))
  let v_float32_operator_info      = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "float32"                              , None                 , Some "ToSingle",  [vara],   ([[varaTy]], v_float32_ty))
  let v_float_operator_info        = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "float"                                , None                 , Some "ToDouble",  [vara],   ([[varaTy]], v_float_ty))
  let v_nativeint_operator_info    = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "nativeint"                            , None                 , Some "ToIntPtr",  [vara],   ([[varaTy]], v_nativeint_ty))
  let v_unativeint_operator_info   = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "unativeint"                           , None                 , Some "ToUIntPtr", [vara],   ([[varaTy]], v_unativeint_ty))

  let v_char_operator_info         = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "char"                                 , None                 , Some "ToChar",    [vara],   ([[varaTy]], v_char_ty))
  let v_enum_operator_info         = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "enum"                                 , None                 , Some "ToEnum",    [vara],   ([[varaTy]], v_enum_ty))

  let v_hash_info                  = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "hash"                                 , None                 , Some "Hash"   , [vara],     ([[varaTy]], v_int_ty))
  let v_box_info                   = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "box"                                  , None                 , Some "Box"    , [vara],     ([[varaTy]], v_obj_ty_with_null))
  let v_isnull_info                = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "isNull"                               , None                 , Some "IsNull" , [vara],     ([[varaTy]], v_bool_ty))
  let v_raise_info                 = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "raise"                                , None                 , Some "Raise"  , [vara],     ([[mkSysNonGenericTy sys "Exception"]], varaTy))
  let v_failwith_info              = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "failwith"                             , None                 , Some "FailWith" , [vara],   ([[v_string_ty]], varaTy))
  let v_invalid_arg_info           = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "invalidArg"                           , None                 , Some "InvalidArg" , [vara], ([[v_string_ty]; [v_string_ty]], varaTy))
  let v_null_arg_info              = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "nullArg"                              , None                 , Some "NullArg" , [vara],    ([[v_string_ty]], varaTy))
  let v_invalid_op_info            = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "invalidOp"                            , None                 , Some "InvalidOp" , [vara],  ([[v_string_ty]], varaTy))
  let v_failwithf_info             = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref,                "failwithf"                            , None                 , Some "PrintFormatToStringThenFail" , [vara;varb], ([[mk_format4_ty varaTy v_unit_ty v_string_ty v_string_ty]], varaTy))

  let v_reraise_info               = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "reraise"                              , None                 , Some "Reraise", [vara],     ([[v_unit_ty]], varaTy))
  let v_typeof_info                = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "typeof"                               , None                 , Some "TypeOf" , [vara],     ([], v_system_Type_ty))
  let v_methodhandleof_info        = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "methodhandleof"                       , None                 , Some "MethodHandleOf", [vara;varb], ([[varaTy --> varbTy]], v_system_RuntimeMethodHandle_ty))
  let v_sizeof_info                = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "sizeof"                               , None                 , Some "SizeOf" , [vara],     ([], v_int_ty))
  let v_nameof_info                = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "nameof"                               , None                 , Some "NameOf" , [vara],     ([[varaTy]], v_string_ty))

  let v_unchecked_defaultof_info   = makeIntrinsicValRef(fslib_MFOperatorsUnchecked_nleref,                    "defaultof"                            , None                 , Some "DefaultOf", [vara],     ([], varaTy))
  let v_typedefof_info             = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "typedefof"                            , None                 , Some "TypeDefOf", [vara],     ([], v_system_Type_ty))
  let v_range_op_info              = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_Range"                             , None                 , None          , [vara],     ([[varaTy];[varaTy]], mkSeqTy varaTy))
  let v_range_step_op_info         = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "op_RangeStep"                         , None                 , None          , [vara;varb], ([[varaTy];[varbTy];[varaTy]], mkSeqTy varaTy))
  let v_range_int32_op_info        = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeInt32"                           , None                 , None          , [],     ([[v_int_ty];[v_int_ty];[v_int_ty]], mkSeqTy v_int_ty))
  let v_range_int64_op_info        = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeInt64"                           , None                 , None          , [],     ([[v_int64_ty];[v_int64_ty];[v_int64_ty]], mkSeqTy v_int64_ty))
  let v_range_uint64_op_info       = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeUInt64"                          , None                 , None          , [],     ([[v_uint64_ty];[v_uint64_ty];[v_uint64_ty]], mkSeqTy v_uint64_ty))
  let v_range_uint32_op_info       = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeUInt32"                          , None                 , None          , [],     ([[v_uint32_ty];[v_uint32_ty];[v_uint32_ty]], mkSeqTy v_uint32_ty))
  let v_range_nativeint_op_info    = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeIntPtr"                          , None                 , None          , [],     ([[v_nativeint_ty];[v_nativeint_ty];[v_nativeint_ty]], mkSeqTy v_nativeint_ty))
  let v_range_unativeint_op_info   = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeUIntPtr"                         , None                 , None          , [],     ([[v_unativeint_ty];[v_unativeint_ty];[v_unativeint_ty]], mkSeqTy v_unativeint_ty))
  let v_range_int16_op_info        = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeInt16"                           , None                 , None          , [],     ([[v_int16_ty];[v_int16_ty];[v_int16_ty]], mkSeqTy v_int16_ty))
  let v_range_uint16_op_info       = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeUInt16"                          , None                 , None          , [],     ([[v_uint16_ty];[v_uint16_ty];[v_uint16_ty]], mkSeqTy v_uint16_ty))
  let v_range_sbyte_op_info        = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeSByte"                           , None                 , None          , [],     ([[v_sbyte_ty];[v_sbyte_ty];[v_sbyte_ty]], mkSeqTy v_sbyte_ty))
  let v_range_byte_op_info         = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeByte"                            , None                 , None          , [],     ([[v_byte_ty];[v_byte_ty];[v_byte_ty]], mkSeqTy v_byte_ty))
  let v_range_char_op_info         = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeChar"                            , None                 , None          , [],     ([[v_char_ty];[v_char_ty];[v_char_ty]], mkSeqTy v_char_ty))
  let v_range_generic_op_info      = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeGeneric"                         , None                 , None          , [vara],      ([[varaTy];[varaTy]], mkSeqTy varaTy))
  let v_range_step_generic_op_info = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref,                    "RangeStepGeneric"                     , None                 , None          , [vara;varb], ([[varaTy];[varbTy];[varaTy]], mkSeqTy varaTy))

  let v_array_length_info          = makeIntrinsicValRef(fslib_MFArrayModule_nleref,                           "length"                               , None                 , Some "Length" , [vara],     ([[mkArrayType 1 varaTy]], v_int_ty))
  let v_array_get_info             = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "GetArray"                             , None                 , None          , [vara],     ([[mkArrayType 1 varaTy]; [v_int_ty]], varaTy))
  let v_array2D_get_info           = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "GetArray2D"                           , None                 , None          , [vara],     ([[mkArrayType 2 varaTy];[v_int_ty]; [v_int_ty]], varaTy))
  let v_array3D_get_info           = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "GetArray3D"                           , None                 , None          , [vara],     ([[mkArrayType 3 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]], varaTy))
  let v_array4D_get_info           = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "GetArray4D"                           , None                 , None          , [vara],     ([[mkArrayType 4 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [v_int_ty]], varaTy))
  let v_array_set_info             = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "SetArray"                             , None                 , None          , [vara],     ([[mkArrayType 1 varaTy]; [v_int_ty]; [varaTy]], v_unit_ty))
  let v_array2D_set_info           = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "SetArray2D"                           , None                 , None          , [vara],     ([[mkArrayType 2 varaTy];[v_int_ty]; [v_int_ty]; [varaTy]], v_unit_ty))
  let v_array3D_set_info           = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "SetArray3D"                           , None                 , None          , [vara],     ([[mkArrayType 3 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [varaTy]], v_unit_ty))
  let v_array4D_set_info           = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "SetArray4D"                           , None                 , None          , [vara],     ([[mkArrayType 4 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [v_int_ty]; [varaTy]], v_unit_ty))

  let v_option_toNullable_info     = makeIntrinsicValRef(fslib_MFOptionModule_nleref,                          "toNullable"                           , None                 , Some "ToNullable" , [vara],     ([[mkOptionTy varaTy]], mkNullableTy varaTy))
  let v_option_defaultValue_info   = makeIntrinsicValRef(fslib_MFOptionModule_nleref,                          "defaultValue"                         , None                 , Some "DefaultValue" , [vara],     ([[varaTy]; [mkOptionTy varaTy]], varaTy))

  let v_nativeptr_tobyref_info     = makeIntrinsicValRef(fslib_MFNativePtrModule_nleref,                       "toByRef"                              , None                 , Some "ToByRefInlined", [vara], ([[mkNativePtrTy varaTy]], mkByrefTy varaTy))

  let v_seq_collect_info           = makeIntrinsicValRef(fslib_MFSeqModule_nleref,                             "collect"                              , None                 , Some "Collect", [vara;varb;varc], ([[varaTy --> varbTy]; [mkSeqTy varaTy]], mkSeqTy varcTy))
  let v_seq_delay_info             = makeIntrinsicValRef(fslib_MFSeqModule_nleref,                             "delay"                                , None                 , Some "Delay"  , [varb],     ([[v_unit_ty --> mkSeqTy varbTy]], mkSeqTy varbTy))
  let v_seq_append_info            = makeIntrinsicValRef(fslib_MFSeqModule_nleref,                             "append"                               , None                 , Some "Append" , [varb],     ([[mkSeqTy varbTy]; [mkSeqTy varbTy]], mkSeqTy varbTy))
  let v_seq_using_info             = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref,                        "EnumerateUsing"                       , None                 , None          , [vara;varb;varc], ([[varaTy];[(varaTy --> varbTy)]], mkSeqTy varcTy))
  let v_seq_generated_info         = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref,                        "EnumerateWhile"                       , None                 , None          , [varb],     ([[v_unit_ty --> v_bool_ty]; [mkSeqTy varbTy]], mkSeqTy varbTy))
  let v_seq_finally_info           = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref,                        "EnumerateThenFinally"                 , None                 , None          , [varb],     ([[mkSeqTy varbTy]; [v_unit_ty --> v_unit_ty]], mkSeqTy varbTy))
  let v_seq_trywith_info           = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref,                        "EnumerateTryWith"                     , None                 , None          , [varb],     ([[mkSeqTy varbTy]; [mkNonGenericTy v_exn_tcr --> v_int32_ty]; [mkNonGenericTy v_exn_tcr --> mkSeqTy varbTy]], mkSeqTy varbTy))
  let v_seq_of_functions_info      = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref,                        "EnumerateFromFunctions"               , None                 , None          , [vara;varb], ([[v_unit_ty --> varaTy]; [varaTy --> v_bool_ty]; [varaTy --> varbTy]], mkSeqTy varbTy))
  let v_create_event_info          = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref,                        "CreateEvent"                          , None                 , None          , [vara;varb], ([[varaTy --> v_unit_ty]; [varaTy --> v_unit_ty]; [(v_obj_ty_with_null --> (varbTy --> v_unit_ty)) --> varaTy]], mkIEvent2Ty varaTy varbTy))
  let v_cgh__useResumableCode_info = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref,                   "__useResumableCode"                   , None                 , None          , [vara],     ([[]], v_bool_ty))
  let v_cgh__debugPoint_info       = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref,                   "__debugPoint"                         , None                 , None          , [vara],     ([[v_int_ty]; [varaTy]], varaTy))
  let v_cgh__resumeAt_info         = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref,                   "__resumeAt"                           , None                 , None          , [vara],     ([[v_int_ty]; [varaTy]], varaTy))
  let v_cgh__stateMachine_info     = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref,                   "__stateMachine"                       , None                 , None          , [vara; varb],     ([[varaTy]], varbTy)) // inaccurate type but it doesn't matter for linking
  let v_cgh__resumableEntry_info   = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref,                   "__resumableEntry"                     , None                 , None          , [vara],     ([[v_int_ty --> varaTy]; [v_unit_ty --> varaTy]], varaTy))
  let v_seq_to_array_info          = makeIntrinsicValRef(fslib_MFSeqModule_nleref,                             "toArray"                              , None                 , Some "ToArray", [varb],     ([[mkSeqTy varbTy]], mkArrayType 1 varbTy))
  let v_seq_to_list_info           = makeIntrinsicValRef(fslib_MFSeqModule_nleref,                             "toList"                               , None                 , Some "ToList" , [varb],     ([[mkSeqTy varbTy]], mkListTy varbTy))
  let v_seq_map_info               = makeIntrinsicValRef(fslib_MFSeqModule_nleref,                             "map"                                  , None                 , Some "Map"    , [vara;varb], ([[varaTy --> varbTy]; [mkSeqTy varaTy]], mkSeqTy varbTy))
  let v_seq_singleton_info         = makeIntrinsicValRef(fslib_MFSeqModule_nleref,                             "singleton"                            , None                 , Some "Singleton"              , [vara],     ([[varaTy]], mkSeqTy varaTy))
  let v_seq_empty_info             = makeIntrinsicValRef(fslib_MFSeqModule_nleref,                             "empty"                                , None                 , Some "Empty"                  , [vara],     ([], mkSeqTy varaTy))
  let v_new_format_info            = makeIntrinsicValRef(fslib_MFCore_nleref,                                  ".ctor"                                , Some "PrintfFormat`5", None                          , [vara;varb;varc;vard;vare], ([[v_string_ty]], mkPrintfFormatTy varaTy varbTy varcTy vardTy vareTy))
  let v_sprintf_info               = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref,                "sprintf"                              , None                 , Some "PrintFormatToStringThen", [vara],     ([[mk_format4_ty varaTy v_unit_ty v_string_ty v_string_ty]], varaTy))
  let v_lazy_force_info            = makeIntrinsicValRef(fslib_MFLazyExtensions_nleref,                        "Force"                                , Some "Lazy`1"        , None                          , [vara],     ([[mkLazyTy varaTy]; []], varaTy))
  let v_lazy_create_info           = makeIntrinsicValRef(fslib_MFLazyExtensions_nleref,                        "Create"                               , Some "Lazy`1"        , None                          , [vara],     ([[v_unit_ty --> varaTy]], mkLazyTy varaTy))

  let v_seq_info                   = makeIntrinsicValRef(fslib_MFOperators_nleref,                             "seq"                                  , None                 , Some "CreateSequence"         , [vara],     ([[mkSeqTy varaTy]], mkSeqTy varaTy))
  let v_splice_expr_info           = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref,                "op_Splice"                            , None                 , None                          , [vara],     ([[mkQuotedExprTy varaTy]], varaTy))
  let v_splice_raw_expr_info       = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref,                "op_SpliceUntyped"                     , None                 , None                          , [vara],     ([[mkRawQuotedExprTy]], varaTy))
  let v_new_decimal_info           = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "MakeDecimal"                          , None                 , None                          , [],         ([[v_int_ty]; [v_int_ty]; [v_int_ty]; [v_bool_ty]; [v_byte_ty]], v_decimal_ty))
  let v_deserialize_quoted_FSharp_20_plus_info    = makeIntrinsicValRef(fslib_MFQuotations_nleref,             "Deserialize"                          , Some "Expr"          , None                          , [],          ([[v_system_Type_ty ;mkListTy v_system_Type_ty ;mkListTy mkRawQuotedExprTy ; mkArrayType 1 v_byte_ty]], mkRawQuotedExprTy ))
  let v_deserialize_quoted_FSharp_40_plus_info    = makeIntrinsicValRef(fslib_MFQuotations_nleref,             "Deserialize40"                        , Some "Expr"          , None                          , [],          ([[v_system_Type_ty ;mkArrayType 1 v_system_Type_ty; mkArrayType 1 v_system_Type_ty; mkArrayType 1 mkRawQuotedExprTy; mkArrayType 1 v_byte_ty]], mkRawQuotedExprTy ))
  let v_call_with_witnesses_info   = makeIntrinsicValRef(fslib_MFQuotations_nleref,                            "CallWithWitnesses"                    , Some "Expr"          , None                          , [],         ([[v_system_Reflection_MethodInfo_ty; v_system_Reflection_MethodInfo_ty; mkListTy mkRawQuotedExprTy; mkListTy mkRawQuotedExprTy]], mkRawQuotedExprTy))
  let v_cast_quotation_info        = makeIntrinsicValRef(fslib_MFQuotations_nleref,                            "Cast"                                 , Some "Expr"          , None                          , [vara],      ([[mkRawQuotedExprTy]], mkQuotedExprTy varaTy))
  let v_lift_value_info            = makeIntrinsicValRef(fslib_MFQuotations_nleref,                            "Value"                                , Some "Expr"          , None                          , [vara],      ([[varaTy]], mkRawQuotedExprTy))
  let v_lift_value_with_name_info  = makeIntrinsicValRef(fslib_MFQuotations_nleref,                            "ValueWithName"                        , Some "Expr"          , None                          , [vara],      ([[varaTy; v_string_ty]], mkRawQuotedExprTy))
  let v_lift_value_with_defn_info  = makeIntrinsicValRef(fslib_MFQuotations_nleref,                            "WithValue"                            , Some "Expr"          , None                          , [vara],      ([[varaTy; mkQuotedExprTy varaTy]], mkQuotedExprTy varaTy))
  let v_query_value_info           = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref,                "query"                                , None                 , None                          , [],      ([], mkQueryBuilderTy) )
  let v_query_run_value_info       = makeIntrinsicValRef(fslib_MFQueryRunExtensionsLowPriority_nleref,         "Run"                                  , Some "QueryBuilder"  , None                          , [vara],      ([[mkQueryBuilderTy];[mkQuotedExprTy varaTy]], varaTy) )
  let v_query_run_enumerable_info  = makeIntrinsicValRef(fslib_MFQueryRunExtensionsHighPriority_nleref,        "Run"                                  , Some "QueryBuilder"  , None                          , [vara],      ([[mkQueryBuilderTy];[mkQuotedExprTy (mkQuerySourceTy varaTy (mkNonGenericTy v_tcref_System_Collections_IEnumerable)) ]], mkSeqTy varaTy) )
  let v_query_for_value_info       = makeIntrinsicValRef(fslib_MFLinq_nleref,                                  "For"                                  , Some "QueryBuilder"  , None                          , [vara; vard; varb; vare], ([[mkQueryBuilderTy];[mkQuerySourceTy varaTy vardTy;varaTy --> mkQuerySourceTy varbTy vareTy]], mkQuerySourceTy varbTy vardTy) )
  let v_query_select_value_info    = makeIntrinsicValRef(fslib_MFLinq_nleref,                                  "Select"                               , Some "QueryBuilder"  , None                          , [vara; vare; varb], ([[mkQueryBuilderTy];[mkQuerySourceTy varaTy vareTy;varaTy --> varbTy]], mkQuerySourceTy varbTy vareTy) )
  let v_query_yield_value_info     = makeIntrinsicValRef(fslib_MFLinq_nleref,                                  "Yield"                                , Some "QueryBuilder"  , None                          , [vara; vare],      ([[mkQueryBuilderTy];[varaTy]], mkQuerySourceTy varaTy vareTy) )
  let v_query_yield_from_value_info = makeIntrinsicValRef(fslib_MFLinq_nleref,                                 "YieldFrom"                            , Some "QueryBuilder"  , None                          , [vara; vare],      ([[mkQueryBuilderTy];[mkQuerySourceTy varaTy vareTy]], mkQuerySourceTy varaTy vareTy) )
  let v_query_source_info          = makeIntrinsicValRef(fslib_MFLinq_nleref,                                  "Source"                               , Some "QueryBuilder"  , None                          , [vara],      ([[mkQueryBuilderTy];[mkSeqTy varaTy ]], mkQuerySourceTy varaTy (mkNonGenericTy v_tcref_System_Collections_IEnumerable)) )
  let v_query_source_as_enum_info  = makeIntrinsicValRef(fslib_MFLinq_nleref,                                  "get_Source"                           , Some "QuerySource`2" , None                          , [vara; vare],      ([[mkQuerySourceTy varaTy vareTy];[]], mkSeqTy varaTy) )
  let v_new_query_source_info     = makeIntrinsicValRef(fslib_MFLinq_nleref,                                  ".ctor"                                 , Some "QuerySource`2" , None                          , [vara; vare],      ([[mkSeqTy varaTy]], mkQuerySourceTy varaTy vareTy) )
  let v_query_zero_value_info      = makeIntrinsicValRef(fslib_MFLinq_nleref,                                  "Zero"                                 , Some "QueryBuilder"  , None                          , [vara; vare],      ([[mkQueryBuilderTy];[]], mkQuerySourceTy varaTy vareTy) )
  let v_fail_init_info             = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "FailInit"                             , None                 , None                          , [],      ([[v_unit_ty]], v_unit_ty))
  let v_fail_static_init_info      = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "FailStaticInit"                       , None                 , None                          , [],      ([[v_unit_ty]], v_unit_ty))
  let v_check_this_info            = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref,                    "CheckThis"                            , None                 , None                          , [vara],      ([[varaTy]], varaTy))
  let v_quote_to_linq_lambda_info  = makeIntrinsicValRef(fslib_MFLinqRuntimeHelpersQuotationConverter_nleref,  "QuotationToLambdaExpression"          , None                 , None                          , [vara],      ([[mkQuotedExprTy varaTy]], mkLinqExpressionTy varaTy))

  let tref_DebuggerNonUserCodeAttribute = findSysILTypeRef tname_DebuggerNonUserCodeAttribute
  let v_DebuggerNonUserCodeAttribute_tcr = splitILTypeName tname_DebuggerNonUserCodeAttribute ||> findSysTyconRef

  let tref_DebuggableAttribute = findSysILTypeRef tname_DebuggableAttribute
  let tref_CompilerGeneratedAttribute  = findSysILTypeRef tname_CompilerGeneratedAttribute
  let v_CompilerGeneratedAttribute_tcr = splitILTypeName tname_CompilerGeneratedAttribute ||> findSysTyconRef
  let tref_InternalsVisibleToAttribute = findSysILTypeRef tname_InternalsVisibleToAttribute

  let debuggerNonUserCodeAttribute = mkILCustomAttribute (tref_DebuggerNonUserCodeAttribute, [], [], [])
  let compilerGeneratedAttribute = mkILCustomAttribute (tref_CompilerGeneratedAttribute, [], [], [])
  let generatedAttributes = if noDebugAttributes then [||] else [| compilerGeneratedAttribute; debuggerNonUserCodeAttribute |]
  let compilerGlobalState = CompilerGlobalState()

  // Requests attributes to be added to compiler generated methods.
  let addGeneratedAttrs (attrs: ILAttributes) =
      if Array.isEmpty generatedAttributes then
          attrs
      else
          match attrs.AsArray() with
          | [||] -> mkILCustomAttrsFromArray generatedAttributes
          | attrs -> mkILCustomAttrsFromArray (Array.append attrs generatedAttributes)

  let addValGeneratedAttrs (v: Val) m =
      if not noDebugAttributes then
          let attrs = [
              Attrib(v_CompilerGeneratedAttribute_tcr, ILAttrib compilerGeneratedAttribute.Method.MethodRef, [], [], false, None, m)
              Attrib(v_DebuggerNonUserCodeAttribute_tcr, ILAttrib debuggerNonUserCodeAttribute.Method.MethodRef, [], [], false, None, m)
              Attrib(v_DebuggerNonUserCodeAttribute_tcr, ILAttrib debuggerNonUserCodeAttribute.Method.MethodRef, [], [], true, None, m)
          ]

          match v.Attribs with
          | [] -> v.SetAttribs attrs
          | _ -> v.SetAttribs (attrs @ v.Attribs)

  let addMethodGeneratedAttrs (mdef:ILMethodDef)   = mdef.With(customAttrs = addGeneratedAttrs mdef.CustomAttrs)

  let addPropertyGeneratedAttrs (pdef:ILPropertyDef) = pdef.With(customAttrs = addGeneratedAttrs pdef.CustomAttrs)

  let addFieldGeneratedAttrs (fdef:ILFieldDef) = fdef.With(customAttrs = addGeneratedAttrs fdef.CustomAttrs)

  let tref_DebuggerBrowsableAttribute n =
        let typ_DebuggerBrowsableState =
            let tref = findSysILTypeRef tname_DebuggerBrowsableState
            ILType.Value (mkILNonGenericTySpec tref)
        mkILCustomAttribute (findSysILTypeRef tname_DebuggerBrowsableAttribute, [typ_DebuggerBrowsableState], [ILAttribElem.Int32 n], [])

  let debuggerBrowsableNeverAttribute = tref_DebuggerBrowsableAttribute 0

  let addNeverAttrs (attrs: ILAttributes) = mkILCustomAttrsFromArray (Array.append (attrs.AsArray()) [| debuggerBrowsableNeverAttribute |])

  let addPropertyNeverAttrs (pdef:ILPropertyDef) = pdef.With(customAttrs = addNeverAttrs pdef.CustomAttrs)

  let addFieldNeverAttrs (fdef:ILFieldDef) = fdef.With(customAttrs = addNeverAttrs fdef.CustomAttrs)

  let mkDebuggerTypeProxyAttribute (ty : ILType) = mkILCustomAttribute (findSysILTypeRef tname_DebuggerTypeProxyAttribute,  [ilg.typ_Type], [ILAttribElem.TypeRef (Some ty.TypeRef)], [])

  let betterTyconEntries =
     [| yield sys, "Int32"    , v_int_tcr
        yield sys, "IntPtr"   , v_nativeint_tcr
        yield sys, "UIntPtr"  , v_unativeint_tcr
        yield sys, "Int16"    , v_int16_tcr
        yield sys, "Int64"    , v_int64_tcr
        yield sys, "UInt16"   , v_uint16_tcr
        yield sys, "UInt32"   , v_uint32_tcr
        yield sys, "UInt64"   , v_uint64_tcr
        yield sys, "SByte"    , v_sbyte_tcr
        yield sys, "Decimal"  , v_decimal_tcr
        yield sys, "Byte"     , v_byte_tcr
        yield sys, "Boolean"  , v_bool_tcr
        yield sys, "String"   , v_string_tcr
        yield sys, "Object"   , v_obj_tcr
        yield sys, "Exception", v_exn_tcr
        yield sys, "Char"     , v_char_tcr
        yield sys, "Double"   , v_float_tcr
        yield sys, "Single"   , v_float32_tcr
        if not compilingFSharpCore then
            yield sysGenerics, "IEnumerable`1", v_seq_tcr |]
            |> Array.map (fun (qualifier, nm, tcr) ->
                let ty = mkNonGenericTy tcr
                nm, findSysTyconRef qualifier nm, (fun typars nullness ->
                    match typars, nullness with
                    | [], Nullness.Known NullnessInfo.WithoutNull -> ty
                    | [], nullness -> mkNonGenericTyWithNullness tcr nullness
                    | _ -> TType_app(tcr, typars, nullness)))

  let decompileTyconEntries =
        [|
            "FSharpFunc`2" ,       v_fastFunc_tcr      , (fun tinst -> mkFunTyWithNullness (List.item 0 tinst) (List.item 1 tinst))
            "Tuple`2"      ,       v_ref_tuple2_tcr    , decodeTupleTyAndNullness tupInfoRef
            "Tuple`3"      ,       v_ref_tuple3_tcr    , decodeTupleTyAndNullness tupInfoRef
            "Tuple`4"      ,       v_ref_tuple4_tcr    , decodeTupleTyAndNullness tupInfoRef
            "Tuple`5"      ,       v_ref_tuple5_tcr    , decodeTupleTyAndNullness tupInfoRef
            "Tuple`6"      ,       v_ref_tuple6_tcr    , decodeTupleTyAndNullness tupInfoRef
            "Tuple`7"      ,       v_ref_tuple7_tcr    , decodeTupleTyAndNullness tupInfoRef
            "Tuple`8"      ,       v_ref_tuple8_tcr    , decodeTupleTyAndNullnessIfPossible v_ref_tuple8_tcr tupInfoRef
            "ValueTuple`2" ,       v_struct_tuple2_tcr , decodeTupleTyAndNullness tupInfoStruct
            "ValueTuple`3" ,       v_struct_tuple3_tcr , decodeTupleTyAndNullness tupInfoStruct
            "ValueTuple`4" ,       v_struct_tuple4_tcr , decodeTupleTyAndNullness tupInfoStruct
            "ValueTuple`5" ,       v_struct_tuple5_tcr , decodeTupleTyAndNullness tupInfoStruct
            "ValueTuple`6" ,       v_struct_tuple6_tcr , decodeTupleTyAndNullness tupInfoStruct
            "ValueTuple`7" ,       v_struct_tuple7_tcr , decodeTupleTyAndNullness tupInfoStruct
            "ValueTuple`8" ,       v_struct_tuple8_tcr , decodeTupleTyAndNullnessIfPossible v_struct_tuple8_tcr tupInfoStruct |]

  let betterEntries = Array.append betterTyconEntries decompileTyconEntries

  let mutable decompileTypeDict = Unchecked.defaultof<_>
  let mutable betterTypeDict1 = Unchecked.defaultof<_>
  let mutable betterTypeDict2 = Unchecked.defaultof<_>

  /// This map is indexed by stamps and lazy to avoid dereferencing while setting up the base imports.
  let getDecompileTypeDict () =
      match box decompileTypeDict with
      | null ->
          let entries = decompileTyconEntries
          let t = Dictionary.newWithSize entries.Length
          for _, tcref, builder in entries do
              if tcref.CanDeref then
                  t.Add(tcref.Stamp, (fun (x, y) -> builder x y))
          decompileTypeDict <- t
          t
      | _ -> decompileTypeDict

  /// This map is for use when building FSharp.Core.dll. The backing Tycon's may not yet exist for
  /// the TyconRef's we have in our hands, hence we can't dereference them to find their stamps.
  /// So this dictionary is indexed by names. Make it lazy to avoid dereferencing while setting up the base imports.
  let getBetterTypeDict1 () =
      match box betterTypeDict1 with
      | null ->
          let entries = betterEntries
          let t = Dictionary.newWithSize entries.Length
          for nm, tcref, builder in entries do
              t.Add(nm,
                     (fun (tcref2, tinst2, nullness) ->
                         if tyconRefEq tcref tcref2 then
                             builder tinst2 nullness
                         else
                             TType_app (tcref2, tinst2, nullness)))
          betterTypeDict1 <- t
          t
      | _ -> betterTypeDict1

  /// This map is for use in normal times (not building FSharp.Core.dll). It is indexed by stamps
  /// and lazy to avoid dereferencing while setting up the base imports.
  let getBetterTypeDict2 () =
      match box betterTypeDict2 with
      | null ->
          let entries = betterEntries
          let t = Dictionary.newWithSize entries.Length
          for _, tcref, builder in entries do
              if tcref.CanDeref then
                  t.Add(tcref.Stamp, (fun (x, y) -> builder x y))
          betterTypeDict2 <- t
          t
      | _ -> betterTypeDict2

  /// For logical purposes equate some F# types with .NET types, e.g. TType_tuple == System.Tuple/ValueTuple.
  /// Doing this normalization is a fairly performance critical piece of code as it is frequently invoked
  /// in the process of converting .NET metadata to F# internal compiler data structures (see import.fs).
  let decompileTy (tcref: EntityRef) tinst nullness =
      if compilingFSharpCore then
          // No need to decompile when compiling FSharp.Core.dll
          TType_app (tcref, tinst, nullness)
      else
          let dict = getDecompileTypeDict()
          match dict.TryGetValue tcref.Stamp with
          | true, builder -> builder (tinst, nullness)
          | _ -> TType_app (tcref, tinst, nullness)

  /// For cosmetic purposes "improve" some .NET types, e.g. Int32 --> int32.
  /// Doing this normalization is a fairly performance critical piece of code as it is frequently invoked
  /// in the process of converting .NET metadata to F# internal compiler data structures (see import.fs).
  let improveTy (tcref: EntityRef) tinst nullness =
        if compilingFSharpCore then
            let dict = getBetterTypeDict1()
            match dict.TryGetValue tcref.LogicalName with
            | true, builder -> builder (tcref, tinst, nullness)
            | _ -> TType_app (tcref, tinst, nullness)
        else
            let dict = getBetterTypeDict2()
            match dict.TryGetValue tcref.Stamp with
            | true, builder -> builder (tinst, nullness)
            | _ -> TType_app (tcref, tinst, nullness)

  // Adding an unnecessary "let" instead of inlining into a multi-line pipelined compute-once "member val" that is too complex for @dsyme
  let v_attribs_Unsupported = [
        tryFindSysAttrib "System.Runtime.CompilerServices.ModuleInitializerAttribute"
        tryFindSysAttrib "System.Runtime.CompilerServices.CallerArgumentExpressionAttribute"
        tryFindSysAttrib "System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute"
        tryFindSysAttrib "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute"
        tryFindSysAttrib "System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute"
        tryFindSysAttrib "System.Runtime.CompilerServices.RequiredMemberAttribute"
                              ] |> List.choose (Option.map (fun x -> x.TyconRef))

  static member IsInEmbeddableKnownSet name = isInEmbeddableKnownSet name

  override _.ToString() = "<TcGlobals>"

  member _.directoryToResolveRelativePaths = directoryToResolveRelativePaths

  member _.ilg = ilg

  member _.noDebugAttributes = noDebugAttributes

  member _.tryFindSysTypeCcuHelper: string list -> string -> bool -> CcuThunk option = tryFindSysTypeCcuHelper

  member _.tryRemoveEmbeddedILTypeDefs () = [
#if FABLE_COMPILER
      for key in embeddedILTypeDefs.Keys do
#else
      for key in embeddedILTypeDefs.Keys.OrderBy id do
#endif
        match embeddedILTypeDefs.TryRemove(key) with
        | true, ilTypeDef -> yield ilTypeDef
        | false, _ -> ()
      ]

  // A table of all intrinsics that the compiler cares about
  member _.knownIntrinsics = v_knownIntrinsics

  member _.checkNullness = checkNullness

  member _.langFeatureNullness = v_langFeatureNullness

  member _.knownWithNull = v_knownWithNull

  member _.knownWithoutNull = v_knownWithoutNull

  // A table of known modules in FSharp.Core. Not all modules are necessarily listed, but the more we list the
  // better the job we do of mapping from provided expressions back to FSharp.Core F# functions and values.
  member _.knownFSharpCoreModules = v_knownFSharpCoreModules

  member _.compilingFSharpCore = compilingFSharpCore

  member _.useReflectionFreeCodeGen = useReflectionFreeCodeGen

  member _.mlCompatibility = mlCompatibility

  member _.emitDebugInfoInQuotations = emitDebugInfoInQuotations

  member _.pathMap = pathMap

  member _.langVersion = langVersion

  member _.realsig = realsig

  member _.unionCaseRefEq x y = primUnionCaseRefEq compilingFSharpCore fslibCcu x y

  member _.valRefEq x y = primValRefEq compilingFSharpCore fslibCcu x y

  member _.fslibCcu = fslibCcu

  member val refcell_tcr_canon = v_refcell_tcr_canon

  member val option_tcr_canon = mk_MFCore_tcref     fslibCcu "Option`1"

  member val valueoption_tcr_canon = mk_MFCore_tcref     fslibCcu "ValueOption`1"

  member _.list_tcr_canon = v_list_tcr_canon

  member _.lazy_tcr_canon = lazy_tcr

  member val refcell_tcr_nice = v_refcell_tcr_nice

  member val array_tcr_nice = v_il_arr_tcr_map[0]

  member _.option_tcr_nice = v_option_tcr_nice

  member _.valueoption_tcr_nice = v_valueoption_tcr_nice

  member _.list_tcr_nice = v_list_tcr_nice

  member _.lazy_tcr_nice = v_lazy_tcr_nice

  member _.format_tcr = v_format_tcr

  member _.format4_tcr = v_format4_tcr

  member _.expr_tcr = v_expr_tcr

  member _.raw_expr_tcr = v_raw_expr_tcr

  member _.nativeint_tcr = v_nativeint_tcr

  member _.int32_tcr = v_int32_tcr

  member _.int16_tcr = v_int16_tcr

  member _.int64_tcr = v_int64_tcr

  member _.uint16_tcr = v_uint16_tcr

  member _.uint32_tcr = v_uint32_tcr

  member _.uint64_tcr = v_uint64_tcr

  member _.sbyte_tcr = v_sbyte_tcr

  member _.decimal_tcr = v_decimal_tcr

  member _.date_tcr = v_date_tcr

  member _.pdecimal_tcr = v_pdecimal_tcr

  member _.byte_tcr = v_byte_tcr

  member _.bool_tcr = v_bool_tcr

  member _.unit_tcr_canon = v_unit_tcr_canon

  member _.exn_tcr = v_exn_tcr

  member _.char_tcr = v_char_tcr

  member _.float_tcr = v_float_tcr

  member _.float32_tcr = v_float32_tcr

  member _.pfloat_tcr = v_pfloat_tcr

  member _.pfloat32_tcr = v_pfloat32_tcr

  member _.pint_tcr = v_pint_tcr

  member _.pint8_tcr = v_pint8_tcr

  member _.pint16_tcr = v_pint16_tcr

  member _.pint64_tcr = v_pint64_tcr

  member _.pnativeint_tcr = v_pnativeint_tcr

  member _.puint_tcr = v_puint_tcr

  member _.puint8_tcr = v_puint8_tcr

  member _.puint16_tcr = v_puint16_tcr

  member _.puint64_tcr = v_puint64_tcr

  member _.punativeint_tcr = v_punativeint_tcr

  member _.byref_tcr = v_byref_tcr

  member _.byref2_tcr = v_byref2_tcr

  member _.outref_tcr = v_outref_tcr

  member _.inref_tcr = v_inref_tcr

  member _.nativeptr_tcr = v_nativeptr_tcr

  member _.voidptr_tcr = v_voidptr_tcr

  member _.ilsigptr_tcr = v_ilsigptr_tcr

  member _.fastFunc_tcr = v_fastFunc_tcr

  member _.MatchFailureException_tcr = v_mfe_tcr


  member _.tcref_IObservable = v_tcref_IObservable

  member _.tcref_IObserver = v_tcref_IObserver

  member _.fslib_IEvent2_tcr = v_fslib_IEvent2_tcr

  member _.fslib_IDelegateEvent_tcr = v_fslib_IDelegateEvent_tcr

  member _.seq_tcr = v_seq_tcr

  member val seq_base_tcr = mk_MFCompilerServices_tcref fslibCcu "GeneratedSequenceBase`1"

  member val ListCollector_tcr = mk_MFCompilerServices_tcref fslibCcu "ListCollector`1"

  member val ArrayCollector_tcr = mk_MFCompilerServices_tcref fslibCcu "ArrayCollector`1"

  member val SupportsWhenTEnum_tcr = mk_MFCompilerServices_tcref fslibCcu "SupportsWhenTEnum"

  member _.TryEmbedILType(tref: ILTypeRef, mkEmbeddableType: unit -> ILTypeDef) =
    if tref.Scope = ILScopeRef.Local && not(embeddedILTypeDefs.ContainsKey(tref.Name)) then
        embeddedILTypeDefs.TryAdd(tref.Name, mkEmbeddableType()) |> ignore

  member g.mk_GeneratedSequenceBase_ty seqElemTy = TType_app(g.seq_base_tcr,[seqElemTy], v_knownWithoutNull)

  member val ResumableStateMachine_tcr = mk_MFCompilerServices_tcref fslibCcu "ResumableStateMachine`1"

  member g.mk_ResumableStateMachine_ty dataTy = TType_app(g.ResumableStateMachine_tcr,[dataTy], v_knownWithoutNull)

  member val IResumableStateMachine_tcr = mk_MFCompilerServices_tcref fslibCcu "IResumableStateMachine`1"

  member g.mk_IResumableStateMachine_ty dataTy = TType_app(g.IResumableStateMachine_tcr,[dataTy], v_knownWithoutNull)

  member g.mk_ListCollector_ty seqElemTy = TType_app(g.ListCollector_tcr,[seqElemTy], v_knownWithoutNull)

  member g.mk_ArrayCollector_ty seqElemTy = TType_app(g.ArrayCollector_tcr,[seqElemTy], v_knownWithoutNull)

  member val byrefkind_In_tcr = mkNonLocalTyconRef fslib_MFByRefKinds_nleref "In"

  member val byrefkind_Out_tcr = mkNonLocalTyconRef fslib_MFByRefKinds_nleref "Out"

  member val byrefkind_InOut_tcr = mkNonLocalTyconRef fslib_MFByRefKinds_nleref "InOut"

  member val measureproduct_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureProduct`2"

  member val measureinverse_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureInverse`1"

  member val measureone_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureOne"

  member val ResumableCode_tcr = mk_MFCompilerServices_tcref fslibCcu "ResumableCode`2"

  member _.il_arr_tcr_map = v_il_arr_tcr_map
  member _.ref_tuple1_tcr = v_ref_tuple1_tcr
  member _.ref_tuple2_tcr = v_ref_tuple2_tcr
  member _.ref_tuple3_tcr = v_ref_tuple3_tcr
  member _.ref_tuple4_tcr = v_ref_tuple4_tcr
  member _.ref_tuple5_tcr = v_ref_tuple5_tcr
  member _.ref_tuple6_tcr = v_ref_tuple6_tcr
  member _.ref_tuple7_tcr = v_ref_tuple7_tcr
  member _.ref_tuple8_tcr = v_ref_tuple8_tcr
  member _.struct_tuple1_tcr = v_struct_tuple1_tcr
  member _.struct_tuple2_tcr = v_struct_tuple2_tcr
  member _.struct_tuple3_tcr = v_struct_tuple3_tcr
  member _.struct_tuple4_tcr = v_struct_tuple4_tcr
  member _.struct_tuple5_tcr = v_struct_tuple5_tcr
  member _.struct_tuple6_tcr = v_struct_tuple6_tcr
  member _.struct_tuple7_tcr = v_struct_tuple7_tcr
  member _.struct_tuple8_tcr = v_struct_tuple8_tcr
  member _.choice2_tcr = v_choice2_tcr
  member _.choice3_tcr = v_choice3_tcr
  member _.choice4_tcr = v_choice4_tcr
  member _.choice5_tcr = v_choice5_tcr
  member _.choice6_tcr = v_choice6_tcr
  member _.choice7_tcr = v_choice7_tcr
  member val nativeint_ty = v_nativeint_ty
  member val unativeint_ty = v_unativeint_ty
  member val int32_ty = v_int32_ty
  member val int16_ty = v_int16_ty
  member val int64_ty = v_int64_ty
  member val uint16_ty = v_uint16_ty
  member val uint32_ty = v_uint32_ty
  member val uint64_ty = v_uint64_ty
  member val sbyte_ty = v_sbyte_ty
  member _.byte_ty = v_byte_ty
  member _.bool_ty = v_bool_ty
  member _.int_ty = v_int_ty
  member _.string_ty = v_string_ty
  member _.string_ty_ambivalent = v_string_ty_ambivalent
  member _.system_IFormattable_tcref = v_IFormattable_tcref
  member _.system_FormattableString_tcref = v_FormattableString_tcref
  member _.system_IFormattable_ty = v_IFormattable_ty
  member _.system_FormattableString_ty = v_FormattableString_ty
  member _.system_FormattableStringFactory_ty = v_FormattableStringFactory_ty
  member _.unit_ty = v_unit_ty
  member _.obj_ty_noNulls = v_obj_ty_without_null
  member _.obj_ty_ambivalent = v_obj_ty_ambivalent
  member _.obj_ty_withNulls = v_obj_ty_with_null
  member _.char_ty = v_char_ty
  member _.decimal_ty = v_decimal_ty

  member val exn_ty = mkNonGenericTy v_exn_tcr
  member val float_ty = v_float_ty
  member val float32_ty = v_float32_ty

  /// Memoization table to help minimize the number of ILSourceDocument objects we create
  member _.memoize_file x = v_memoize_file.Apply x

  member val system_Array_ty = mkSysNonGenericTy sys "Array"
  member val system_Object_ty = mkSysNonGenericTy sys "Object"
  member val system_IDisposable_ty = mkSysNonGenericTy sys "IDisposable"
  member val system_IDisposableNull_ty = mkNonGenericTyWithNullness (findSysTyconRef sys "IDisposable") v_knownWithNull
  member val system_RuntimeHelpers_ty = mkSysNonGenericTy sysCompilerServices "RuntimeHelpers"
  member val system_Value_ty = mkSysNonGenericTy sys "ValueType"
  member val system_Delegate_ty = mkSysNonGenericTy sys "Delegate"
  member val system_MulticastDelegate_ty = mkSysNonGenericTy sys "MulticastDelegate"
  member val system_Enum_ty = mkSysNonGenericTy sys "Enum"
  member val system_String_tcref = findSysTyconRef sys "String"
  member _.system_Type_ty = v_system_Type_ty
  member val system_TypedReference_tcref = tryFindSysTyconRef sys "TypedReference"
  member val system_ArgIterator_tcref = tryFindSysTyconRef sys "ArgIterator"
  member val system_RuntimeArgumentHandle_tcref = tryFindSysTyconRef sys "RuntimeArgumentHandle"
  member val system_SByte_tcref = findSysTyconRef sys "SByte"
  member val system_Decimal_tcref = findSysTyconRef sys "Decimal"
  member val system_Int16_tcref = findSysTyconRef sys "Int16"
  member val system_Int32_tcref = findSysTyconRef sys "Int32"
  member val system_Int64_tcref = findSysTyconRef sys "Int64"
  member val system_IntPtr_tcref = findSysTyconRef sys "IntPtr"
  member val system_Bool_tcref = findSysTyconRef sys "Boolean"
  member val system_Byte_tcref = findSysTyconRef sys "Byte"
  member val system_UInt16_tcref = findSysTyconRef sys "UInt16"
  member val system_Char_tcref = findSysTyconRef sys "Char"
  member val system_UInt32_tcref = findSysTyconRef sys "UInt32"
  member val system_UInt64_tcref = findSysTyconRef sys "UInt64"
  member val system_UIntPtr_tcref = findSysTyconRef sys "UIntPtr"
  member val system_Single_tcref = findSysTyconRef sys "Single"
  member val system_Double_tcref = findSysTyconRef sys "Double"
  member val system_RuntimeTypeHandle_ty = mkSysNonGenericTy sys "RuntimeTypeHandle"

  member val system_MarshalByRefObject_tcref = tryFindSysTyconRef sys "MarshalByRefObject"
  member val system_MarshalByRefObject_ty = tryMkSysNonGenericTy sys "MarshalByRefObject"

  member val system_ExceptionDispatchInfo_ty =
      tryMkSysNonGenericTy ["System"; "Runtime"; "ExceptionServices"] "ExceptionDispatchInfo"

  member _.mk_IAsyncStateMachine_ty = mkSysNonGenericTy sysCompilerServices "IAsyncStateMachine"

  member val system_Object_tcref = findSysTyconRef sys "Object"
  member val system_Value_tcref = findSysTyconRef sys "ValueType"
  member val system_Void_tcref = findSysTyconRef sys "Void"
  member val system_Nullable_tcref = v_nullable_tcr
  member val system_GenericIComparable_tcref = findSysTyconRef sys "IComparable`1"
  member val system_GenericIEquatable_tcref = findSysTyconRef sys "IEquatable`1"
  member val mk_IComparable_ty    = mkSysNonGenericTy sys "IComparable"
  member val mk_Attribute_ty = mkSysNonGenericTy sys "Attribute"
  member val system_LinqExpression_tcref = v_linqExpression_tcr

  member val mk_IStructuralComparable_ty = mkSysNonGenericTy sysCollections "IStructuralComparable"

  member val mk_IStructuralEquatable_ty = mkSysNonGenericTy sysCollections "IStructuralEquatable"

  member _.IComparer_ty = v_IComparer_ty
  member _.IEqualityComparer_ty = v_IEqualityComparer_ty
  member val tcref_System_Collections_IComparer = findSysTyconRef sysCollections "IComparer"
  member val tcref_System_Collections_IEqualityComparer = findSysTyconRef sysCollections "IEqualityComparer"
  member val tcref_System_Collections_Generic_IEqualityComparer = findSysTyconRef sysGenerics "IEqualityComparer`1"
  member val tcref_System_Collections_Generic_Dictionary = findSysTyconRef sysGenerics "Dictionary`2"

  member val tcref_System_IComparable = findSysTyconRef sys "IComparable"
  member val tcref_System_IStructuralComparable = findSysTyconRef sysCollections "IStructuralComparable"
  member val tcref_System_IStructuralEquatable = findSysTyconRef sysCollections "IStructuralEquatable"
  member val tcref_System_IDisposable = findSysTyconRef sys "IDisposable"

  member val tcref_LanguagePrimitives = mk_MFCore_tcref fslibCcu "LanguagePrimitives"

  member val tcref_System_Collections_Generic_IList = findSysTyconRef sysGenerics "IList`1"
  member val tcref_System_Collections_Generic_IReadOnlyList = findSysTyconRef sysGenerics "IReadOnlyList`1"
  member val tcref_System_Collections_Generic_ICollection = findSysTyconRef sysGenerics "ICollection`1"
  member val tcref_System_Collections_Generic_IReadOnlyCollection = findSysTyconRef sysGenerics "IReadOnlyCollection`1"
  member _.tcref_System_Collections_IEnumerable = v_tcref_System_Collections_IEnumerable

  member _.tcref_System_Collections_Generic_IEnumerable = v_IEnumerable_tcr
  member _.tcref_System_Collections_Generic_IEnumerator = v_IEnumerator_tcr

  member _.tcref_System_Attribute = v_System_Attribute_tcr

  // Review: Does this need to be an option type?
  member val System_Runtime_CompilerServices_RuntimeFeature_ty = tryFindSysTyconRef sysCompilerServices "RuntimeFeature" |> Option.map mkNonGenericTy

  member val iltyp_StreamingContext = tryFindSysILTypeRef tname_StreamingContext  |> Option.map mkILNonGenericValueTy
  member val iltyp_SerializationInfo = tryFindSysILTypeRef tname_SerializationInfo  |> Option.map mkILNonGenericBoxedTy
  member val iltyp_Missing = findSysILTypeRef tname_Missing |> mkILNonGenericBoxedTy
  member val iltyp_AsyncCallback = findSysILTypeRef tname_AsyncCallback |> mkILNonGenericBoxedTy
  member val iltyp_IAsyncResult = findSysILTypeRef tname_IAsyncResult |> mkILNonGenericBoxedTy
  member val iltyp_IComparable = findSysILTypeRef tname_IComparable |> mkILNonGenericBoxedTy
  member val iltyp_Exception = findSysILTypeRef tname_Exception |> mkILNonGenericBoxedTy
  member val iltyp_ValueType = findSysILTypeRef tname_ValueType |> mkILNonGenericBoxedTy
  member val iltyp_RuntimeFieldHandle = findSysILTypeRef tname_RuntimeFieldHandle |> mkILNonGenericValueTy
  member val iltyp_RuntimeMethodHandle = findSysILTypeRef tname_RuntimeMethodHandle |> mkILNonGenericValueTy
  member val iltyp_RuntimeTypeHandle   = findSysILTypeRef tname_RuntimeTypeHandle |> mkILNonGenericValueTy
  member val iltyp_ReferenceAssemblyAttributeOpt = tryFindSysILTypeRef tname_ReferenceAssemblyAttribute |> Option.map mkILNonGenericBoxedTy
  member val iltyp_UnmanagedType   = findSysILTypeRef tname_UnmanagedType |> mkILNonGenericValueTy
  member val attrib_AttributeUsageAttribute = findSysAttrib "System.AttributeUsageAttribute"
  member val attrib_ParamArrayAttribute = findSysAttrib "System.ParamArrayAttribute"
  member val attrib_IDispatchConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IDispatchConstantAttribute"
  member val attrib_IUnknownConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IUnknownConstantAttribute"
  member val attrib_RequiresLocationAttribute = findSysAttrib "System.Runtime.CompilerServices.RequiresLocationAttribute"

  // We use 'findSysAttrib' here because lookup on attribute is done by name comparison, and can proceed
  // even if the type is not found in a system assembly.
  member val attrib_IsReadOnlyAttribute = findOrEmbedSysPublicType "System.Runtime.CompilerServices.IsReadOnlyAttribute"
  member val attrib_IsUnmanagedAttribute = findOrEmbedSysPublicType "System.Runtime.CompilerServices.IsUnmanagedAttribute"
  member val attrib_DynamicDependencyAttribute = findOrEmbedSysPublicType "System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute"
  member val attrib_NullableAttribute_opt = tryFindSysAttrib "System.Runtime.CompilerServices.NullableAttribute"
  member val attrib_NullableContextAttribute_opt = tryFindSysAttrib "System.Runtime.CompilerServices.NullableContextAttribute"
  member val attrib_NullableAttribute = findOrEmbedSysPublicType "System.Runtime.CompilerServices.NullableAttribute"
  member val attrib_NullableContextAttribute = findOrEmbedSysPublicType "System.Runtime.CompilerServices.NullableContextAttribute"
  member val attrib_MemberNotNullWhenAttribute  = findOrEmbedSysPublicType "System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute"
  member val enum_DynamicallyAccessedMemberTypes = findOrEmbedSysPublicType "System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes"

  member val attrib_SystemObsolete = findSysAttrib "System.ObsoleteAttribute"
  member val attrib_IsByRefLikeAttribute_opt = tryFindSysAttrib "System.Runtime.CompilerServices.IsByRefLikeAttribute"
  member val attrib_DllImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DllImportAttribute"
  member val attrib_StructLayoutAttribute = findSysAttrib "System.Runtime.InteropServices.StructLayoutAttribute"
  member val attrib_TypeForwardedToAttribute = findSysAttrib "System.Runtime.CompilerServices.TypeForwardedToAttribute"
  member val attrib_ComVisibleAttribute = findSysAttrib "System.Runtime.InteropServices.ComVisibleAttribute"
  member val attrib_ComImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.ComImportAttribute"
  member val attrib_FieldOffsetAttribute = findSysAttrib "System.Runtime.InteropServices.FieldOffsetAttribute"
  member val attrib_MarshalAsAttribute = tryFindSysAttrib "System.Runtime.InteropServices.MarshalAsAttribute"
  member val attrib_InAttribute = findSysAttrib "System.Runtime.InteropServices.InAttribute"
  member val attrib_OutAttribute = findSysAttrib "System.Runtime.InteropServices.OutAttribute"
  member val attrib_OptionalAttribute = tryFindSysAttrib "System.Runtime.InteropServices.OptionalAttribute"
  member val attrib_DefaultParameterValueAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DefaultParameterValueAttribute"
  member val attrib_ThreadStaticAttribute = tryFindSysAttrib "System.ThreadStaticAttribute"
  member val attrib_VolatileFieldAttribute = mk_MFCore_attrib "VolatileFieldAttribute"
  member val attrib_NoEagerConstraintApplicationAttribute = mk_MFCompilerServices_attrib "NoEagerConstraintApplicationAttribute"
  member val attrib_ContextStaticAttribute = tryFindSysAttrib "System.ContextStaticAttribute"
  member val attrib_FlagsAttribute = findSysAttrib "System.FlagsAttribute"
  member val attrib_DefaultMemberAttribute = findSysAttrib "System.Reflection.DefaultMemberAttribute"
  member val attrib_DebuggerDisplayAttribute = findSysAttrib "System.Diagnostics.DebuggerDisplayAttribute"
  member val attrib_DebuggerTypeProxyAttribute = findSysAttrib "System.Diagnostics.DebuggerTypeProxyAttribute"
  member val attrib_PreserveSigAttribute = tryFindSysAttrib "System.Runtime.InteropServices.PreserveSigAttribute"
  member val attrib_MethodImplAttribute = findSysAttrib "System.Runtime.CompilerServices.MethodImplAttribute"
  member val attrib_ExtensionAttribute = findSysAttrib "System.Runtime.CompilerServices.ExtensionAttribute"
  member val attrib_CallerLineNumberAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerLineNumberAttribute"
  member val attrib_CallerFilePathAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerFilePathAttribute"
  member val attrib_CallerMemberNameAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerMemberNameAttribute"
  member val attrib_SkipLocalsInitAttribute  = findSysAttrib "System.Runtime.CompilerServices.SkipLocalsInitAttribute"
  member val attrib_DecimalConstantAttribute = findSysAttrib "System.Runtime.CompilerServices.DecimalConstantAttribute"
  member val attribs_Unsupported = v_attribs_Unsupported

  member val attrib_ProjectionParameterAttribute           = mk_MFCore_attrib "ProjectionParameterAttribute"
  member val attrib_CustomOperationAttribute               = mk_MFCore_attrib "CustomOperationAttribute"
  member val attrib_NonSerializedAttribute                 = tryFindSysAttrib "System.NonSerializedAttribute"

  member val attrib_AutoSerializableAttribute              = mk_MFCore_attrib "AutoSerializableAttribute"
  member val attrib_RequireQualifiedAccessAttribute        = mk_MFCore_attrib "RequireQualifiedAccessAttribute"
  member val attrib_EntryPointAttribute                    = mk_MFCore_attrib "EntryPointAttribute"
  member val attrib_DefaultAugmentationAttribute           = mk_MFCore_attrib "DefaultAugmentationAttribute"
  member val attrib_CompilerMessageAttribute               = mk_MFCore_attrib "CompilerMessageAttribute"
  member val attrib_ExperimentalAttribute                  = mk_MFCore_attrib "ExperimentalAttribute"
  member val attrib_UnverifiableAttribute                  = mk_MFCore_attrib "UnverifiableAttribute"
  member val attrib_LiteralAttribute                       = mk_MFCore_attrib "LiteralAttribute"
  member val attrib_ConditionalAttribute                   = findSysAttrib "System.Diagnostics.ConditionalAttribute"
  member val attrib_OptionalArgumentAttribute              = mk_MFCore_attrib "OptionalArgumentAttribute"
  member val attrib_RequiresExplicitTypeArgumentsAttribute = mk_MFCore_attrib "RequiresExplicitTypeArgumentsAttribute"
  member val attrib_DefaultValueAttribute                  = mk_MFCore_attrib "DefaultValueAttribute"
  member val attrib_ClassAttribute                         = mk_MFCore_attrib "ClassAttribute"
  member val attrib_InterfaceAttribute                     = mk_MFCore_attrib "InterfaceAttribute"
  member val attrib_StructAttribute                        = mk_MFCore_attrib "StructAttribute"
  member val attrib_ReflectedDefinitionAttribute           = mk_MFCore_attrib "ReflectedDefinitionAttribute"
  member val attrib_CompiledNameAttribute                  = mk_MFCore_attrib "CompiledNameAttribute"
  member val attrib_AutoOpenAttribute                      = mk_MFCore_attrib "AutoOpenAttribute"
  member val attrib_InternalsVisibleToAttribute            = findSysAttrib tname_InternalsVisibleToAttribute
  member val attrib_CompilationRepresentationAttribute     = mk_MFCore_attrib "CompilationRepresentationAttribute"
  member val attrib_CompilationArgumentCountsAttribute     = mk_MFCore_attrib "CompilationArgumentCountsAttribute"
  member val attrib_CompilationMappingAttribute            = mk_MFCore_attrib "CompilationMappingAttribute"
  member val attrib_CLIEventAttribute                      = mk_MFCore_attrib "CLIEventAttribute"
  member val attrib_InlineIfLambdaAttribute                = mk_MFCore_attrib "InlineIfLambdaAttribute"
  member val attrib_CLIMutableAttribute                    = mk_MFCore_attrib "CLIMutableAttribute"
  member val attrib_AllowNullLiteralAttribute              = mk_MFCore_attrib "AllowNullLiteralAttribute"
  member val attrib_NoEqualityAttribute                    = mk_MFCore_attrib "NoEqualityAttribute"
  member val attrib_NoComparisonAttribute                  = mk_MFCore_attrib "NoComparisonAttribute"
  member val attrib_CustomEqualityAttribute                = mk_MFCore_attrib "CustomEqualityAttribute"
  member val attrib_CustomComparisonAttribute              = mk_MFCore_attrib "CustomComparisonAttribute"
  member val attrib_EqualityConditionalOnAttribute         = mk_MFCore_attrib "EqualityConditionalOnAttribute"
  member val attrib_ComparisonConditionalOnAttribute       = mk_MFCore_attrib "ComparisonConditionalOnAttribute"
  member val attrib_ReferenceEqualityAttribute             = mk_MFCore_attrib "ReferenceEqualityAttribute"
  member val attrib_StructuralEqualityAttribute            = mk_MFCore_attrib "StructuralEqualityAttribute"
  member val attrib_StructuralComparisonAttribute          = mk_MFCore_attrib "StructuralComparisonAttribute"
  member val attrib_SealedAttribute                        = mk_MFCore_attrib "SealedAttribute"
  member val attrib_AbstractClassAttribute                 = mk_MFCore_attrib "AbstractClassAttribute"
  member val attrib_GeneralizableValueAttribute            = mk_MFCore_attrib "GeneralizableValueAttribute"
  member val attrib_MeasureAttribute                       = mk_MFCore_attrib "MeasureAttribute"
  member val attrib_MeasureableAttribute                   = mk_MFCore_attrib "MeasureAnnotatedAbbreviationAttribute"
  member val attrib_NoDynamicInvocationAttribute           = mk_MFCore_attrib "NoDynamicInvocationAttribute"
  member val attrib_NoCompilerInliningAttribute            = mk_MFCore_attrib "NoCompilerInliningAttribute"
  member val attrib_WarnOnWithoutNullArgumentAttribute      = mk_MFCore_attrib "WarnOnWithoutNullArgumentAttribute"
  member val attrib_SecurityAttribute                      = tryFindSysAttrib "System.Security.Permissions.SecurityAttribute"
  member val attrib_SecurityCriticalAttribute              = findSysAttrib "System.Security.SecurityCriticalAttribute"
  member val attrib_SecuritySafeCriticalAttribute          = findSysAttrib "System.Security.SecuritySafeCriticalAttribute"
  member val attrib_ComponentModelEditorBrowsableAttribute = findSysAttrib "System.ComponentModel.EditorBrowsableAttribute"
  member val attrib_CompilerFeatureRequiredAttribute       = findSysAttrib "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute"
  member val attrib_SetsRequiredMembersAttribute           = findSysAttrib "System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute"
  member val attrib_RequiredMemberAttribute                = findSysAttrib "System.Runtime.CompilerServices.RequiredMemberAttribute"
  member val attrib_IlExperimentalAttribute                   = findSysAttrib "System.Diagnostics.CodeAnalysis.ExperimentalAttribute"

  member g.improveType tcref tinst = improveTy tcref tinst

  member g.decompileType tcref tinst = decompileTy tcref tinst

  member _.new_decimal_info = v_new_decimal_info
  member _.seq_info    = v_seq_info
  member val seq_vref    = (ValRefForIntrinsic v_seq_info)
  member val and_vref    = (ValRefForIntrinsic v_and_info)
  member val and2_vref   = (ValRefForIntrinsic v_and2_info)
  member val addrof_vref = (ValRefForIntrinsic v_addrof_info)
  member val addrof2_vref = (ValRefForIntrinsic v_addrof2_info)
  member val or_vref     = (ValRefForIntrinsic v_or_info)
  member val splice_expr_vref     = (ValRefForIntrinsic v_splice_expr_info)
  member val splice_raw_expr_vref     = (ValRefForIntrinsic v_splice_raw_expr_info)
  member val or2_vref    = (ValRefForIntrinsic v_or2_info)
  member val generic_equality_er_inner_vref     = ValRefForIntrinsic v_generic_equality_er_inner_info
  member val generic_equality_per_inner_vref = ValRefForIntrinsic v_generic_equality_per_inner_info
  member val generic_equality_withc_inner_vref  = ValRefForIntrinsic v_generic_equality_withc_inner_info
  member val generic_comparison_inner_vref    = ValRefForIntrinsic v_generic_comparison_inner_info
  member val generic_comparison_withc_inner_vref    = ValRefForIntrinsic v_generic_comparison_withc_inner_info
  member _.generic_comparison_withc_outer_info    = v_generic_comparison_withc_outer_info
  member _.generic_equality_er_outer_info     = v_generic_equality_er_outer_info
  member _.generic_equality_withc_outer_info  = v_generic_equality_withc_outer_info
  member _.generic_hash_withc_outer_info = v_generic_hash_withc_outer_info
  member val generic_hash_inner_vref = ValRefForIntrinsic v_generic_hash_inner_info
  member val generic_hash_withc_inner_vref = ValRefForIntrinsic v_generic_hash_withc_inner_info

  member val reference_equality_inner_vref         = ValRefForIntrinsic v_reference_equality_inner_info

  member val piperight_vref            = ValRefForIntrinsic v_piperight_info
  member val piperight2_vref            = ValRefForIntrinsic v_piperight2_info
  member val piperight3_vref            = ValRefForIntrinsic v_piperight3_info
  member val bitwise_or_vref            = ValRefForIntrinsic v_bitwise_or_info
  member val bitwise_and_vref           = ValRefForIntrinsic v_bitwise_and_info
  member val bitwise_xor_vref           = ValRefForIntrinsic v_bitwise_xor_info
  member val bitwise_unary_not_vref     = ValRefForIntrinsic v_bitwise_unary_not_info
  member val bitwise_shift_left_vref    = ValRefForIntrinsic v_bitwise_shift_left_info
  member val bitwise_shift_right_vref   = ValRefForIntrinsic v_bitwise_shift_right_info
  member val exponentiation_vref        = ValRefForIntrinsic v_exponentiation_info
  member val unchecked_addition_vref    = ValRefForIntrinsic v_unchecked_addition_info
  member val unchecked_unary_plus_vref  = ValRefForIntrinsic v_unchecked_unary_plus_info
  member val unchecked_unary_minus_vref = ValRefForIntrinsic v_unchecked_unary_minus_info
  member val unchecked_unary_not_vref = ValRefForIntrinsic v_unchecked_unary_not_info
  member val unchecked_subtraction_vref = ValRefForIntrinsic v_unchecked_subtraction_info
  member val unchecked_multiply_vref    = ValRefForIntrinsic v_unchecked_multiply_info
  member val unchecked_division_vref    = ValRefForIntrinsic v_unchecked_division_info
  member val unchecked_modulus_vref     = ValRefForIntrinsic v_unchecked_modulus_info
  member val unchecked_defaultof_vref    = ValRefForIntrinsic v_unchecked_defaultof_info
  member val refcell_deref_vref = ValRefForIntrinsic v_refcell_deref_info
  member val refcell_assign_vref = ValRefForIntrinsic v_refcell_assign_info
  member val refcell_incr_vref = ValRefForIntrinsic v_refcell_incr_info
  member val refcell_decr_vref = ValRefForIntrinsic v_refcell_decr_info

  member _.bitwise_or_info            = v_bitwise_or_info
  member _.bitwise_and_info           = v_bitwise_and_info
  member _.bitwise_xor_info           = v_bitwise_xor_info
  member _.bitwise_unary_not_info     = v_bitwise_unary_not_info
  member _.bitwise_shift_left_info    = v_bitwise_shift_left_info
  member _.bitwise_shift_right_info   = v_bitwise_shift_right_info
  member _.unchecked_addition_info    = v_unchecked_addition_info
  member _.unchecked_subtraction_info = v_unchecked_subtraction_info
  member _.unchecked_multiply_info    = v_unchecked_multiply_info
  member _.unchecked_division_info    = v_unchecked_division_info
  member _.unchecked_modulus_info     = v_unchecked_modulus_info
  member _.unchecked_unary_minus_info = v_unchecked_unary_minus_info
  member _.unchecked_defaultof_info   = v_unchecked_defaultof_info

  member _.checked_addition_info      = v_checked_addition_info
  member _.checked_subtraction_info   = v_checked_subtraction_info
  member _.checked_multiply_info      = v_checked_multiply_info
  member _.checked_unary_minus_info   = v_checked_unary_minus_info

  member _.byte_checked_info          = v_byte_checked_info
  member _.sbyte_checked_info         = v_sbyte_checked_info
  member _.int16_checked_info         = v_int16_checked_info
  member _.uint16_checked_info        = v_uint16_checked_info
  member _.int_checked_info           = v_int_checked_info
  member _.int32_checked_info         = v_int32_checked_info
  member _.uint32_checked_info        = v_uint32_checked_info
  member _.int64_checked_info         = v_int64_checked_info
  member _.uint64_checked_info        = v_uint64_checked_info
  member _.nativeint_checked_info     = v_nativeint_checked_info
  member _.unativeint_checked_info    = v_unativeint_checked_info

  member _.byte_operator_info       = v_byte_operator_info
  member _.sbyte_operator_info      = v_sbyte_operator_info
  member _.int16_operator_info      = v_int16_operator_info
  member _.uint16_operator_info     = v_uint16_operator_info
  member _.int32_operator_info      = v_int32_operator_info
  member _.uint32_operator_info     = v_uint32_operator_info
  member _.int64_operator_info      = v_int64_operator_info
  member _.uint64_operator_info     = v_uint64_operator_info
  member _.float32_operator_info    = v_float32_operator_info
  member _.float_operator_info      = v_float_operator_info
  member _.nativeint_operator_info  = v_nativeint_operator_info
  member _.unativeint_operator_info = v_unativeint_operator_info

  member _.char_operator_info       = v_char_operator_info
  member _.enum_operator_info       = v_enum_operator_info

  member val compare_operator_vref    = ValRefForIntrinsic v_compare_operator_info
  member val equals_operator_vref    = ValRefForIntrinsic v_equals_operator_info
  member val equals_nullable_operator_vref    = ValRefForIntrinsic v_equals_nullable_operator_info
  member val nullable_equals_nullable_operator_vref    = ValRefForIntrinsic v_nullable_equals_nullable_operator_info
  member val nullable_equals_operator_vref    = ValRefForIntrinsic v_nullable_equals_operator_info
  member val not_equals_operator_vref    = ValRefForIntrinsic v_not_equals_operator_info
  member val less_than_operator_vref    = ValRefForIntrinsic v_less_than_operator_info
  member val less_than_or_equals_operator_vref    = ValRefForIntrinsic v_less_than_or_equals_operator_info
  member val greater_than_operator_vref    = ValRefForIntrinsic v_greater_than_operator_info
  member val greater_than_or_equals_operator_vref    = ValRefForIntrinsic v_greater_than_or_equals_operator_info

  member val raise_vref                 = ValRefForIntrinsic v_raise_info
  member val failwith_vref              = ValRefForIntrinsic v_failwith_info
  member val invalid_arg_vref           = ValRefForIntrinsic v_invalid_arg_info
  member val null_arg_vref              = ValRefForIntrinsic v_null_arg_info
  member val invalid_op_vref            = ValRefForIntrinsic v_invalid_op_info
  member val failwithf_vref             = ValRefForIntrinsic v_failwithf_info

  member _.equals_operator_info        = v_equals_operator_info
  member _.not_equals_operator         = v_not_equals_operator_info
  member _.less_than_operator          = v_less_than_operator_info
  member _.less_than_or_equals_operator = v_less_than_or_equals_operator_info
  member _.greater_than_operator       = v_greater_than_operator_info
  member _.greater_than_or_equals_operator = v_greater_than_or_equals_operator_info

  member _.hash_info                  = v_hash_info
  member _.box_info                   = v_box_info
  member _.isnull_info                = v_isnull_info
  member _.raise_info                 = v_raise_info
  member _.reraise_info               = v_reraise_info
  member _.typeof_info                = v_typeof_info
  member _.typedefof_info             = v_typedefof_info

  member val reraise_vref               = ValRefForIntrinsic v_reraise_info
  member val methodhandleof_vref        = ValRefForIntrinsic v_methodhandleof_info
  member val typeof_vref                = ValRefForIntrinsic v_typeof_info
  member val sizeof_vref                = ValRefForIntrinsic v_sizeof_info
  member val nameof_vref                = ValRefForIntrinsic v_nameof_info
  member val typedefof_vref             = ValRefForIntrinsic v_typedefof_info
  member val enum_vref                  = ValRefForIntrinsic v_enum_operator_info
  member val enumOfValue_vref           = ValRefForIntrinsic v_enumOfValue_info
  member val range_op_vref              = ValRefForIntrinsic v_range_op_info
  member val range_step_op_vref         = ValRefForIntrinsic v_range_step_op_info
  member val range_int32_op_vref        = ValRefForIntrinsic v_range_int32_op_info
  member val range_int64_op_vref        = ValRefForIntrinsic v_range_int64_op_info
  member val range_uint64_op_vref       = ValRefForIntrinsic v_range_uint64_op_info
  member val range_uint32_op_vref       = ValRefForIntrinsic v_range_uint32_op_info
  member val range_nativeint_op_vref    = ValRefForIntrinsic v_range_nativeint_op_info
  member val range_unativeint_op_vref   = ValRefForIntrinsic v_range_unativeint_op_info
  member val range_int16_op_vref        = ValRefForIntrinsic v_range_int16_op_info
  member val range_uint16_op_vref       = ValRefForIntrinsic v_range_uint16_op_info
  member val range_sbyte_op_vref        = ValRefForIntrinsic v_range_sbyte_op_info
  member val range_byte_op_vref         = ValRefForIntrinsic v_range_byte_op_info
  member val range_char_op_vref         = ValRefForIntrinsic v_range_char_op_info
  member val range_generic_op_vref      = ValRefForIntrinsic v_range_generic_op_info
  member val range_step_generic_op_vref = ValRefForIntrinsic v_range_step_generic_op_info
  member val array_get_vref             = ValRefForIntrinsic v_array_get_info
  member val array2D_get_vref           = ValRefForIntrinsic v_array2D_get_info
  member val array3D_get_vref           = ValRefForIntrinsic v_array3D_get_info
  member val array4D_get_vref           = ValRefForIntrinsic v_array4D_get_info
  member val seq_singleton_vref         = ValRefForIntrinsic v_seq_singleton_info
  member val seq_collect_vref           = ValRefForIntrinsic v_seq_collect_info
  member val nativeptr_tobyref_vref     = ValRefForIntrinsic v_nativeptr_tobyref_info
  member val seq_using_vref             = ValRefForIntrinsic v_seq_using_info
  member val seq_delay_vref             = ValRefForIntrinsic  v_seq_delay_info
  member val seq_append_vref            = ValRefForIntrinsic  v_seq_append_info
  member val seq_generated_vref         = ValRefForIntrinsic  v_seq_generated_info
  member val seq_finally_vref           = ValRefForIntrinsic  v_seq_finally_info
  member val seq_map_vref               = ValRefForIntrinsic  v_seq_map_info
  member val seq_empty_vref             = ValRefForIntrinsic  v_seq_empty_info
  member val new_format_vref            = ValRefForIntrinsic v_new_format_info
  member val sprintf_vref               = ValRefForIntrinsic v_sprintf_info
  member val unbox_vref                 = ValRefForIntrinsic v_unbox_info
  member val unbox_fast_vref            = ValRefForIntrinsic v_unbox_fast_info
  member val istype_vref                = ValRefForIntrinsic v_istype_info
  member val istype_fast_vref           = ValRefForIntrinsic v_istype_fast_info
  member val query_source_vref          = ValRefForIntrinsic v_query_source_info
  member val query_value_vref           = ValRefForIntrinsic v_query_value_info
  member val query_run_value_vref       = ValRefForIntrinsic v_query_run_value_info
  member val query_run_enumerable_vref  = ValRefForIntrinsic v_query_run_enumerable_info
  member val query_for_vref             = ValRefForIntrinsic v_query_for_value_info
  member val query_yield_vref           = ValRefForIntrinsic v_query_yield_value_info
  member val query_yield_from_vref      = ValRefForIntrinsic v_query_yield_from_value_info
  member val query_select_vref          = ValRefForIntrinsic v_query_select_value_info
  member val query_zero_vref            = ValRefForIntrinsic v_query_zero_value_info
  member val seq_to_list_vref           = ValRefForIntrinsic v_seq_to_list_info
  member val seq_to_array_vref          = ValRefForIntrinsic v_seq_to_array_info

  member _.seq_collect_info           = v_seq_collect_info
  member _.seq_using_info             = v_seq_using_info
  member _.seq_delay_info             = v_seq_delay_info
  member _.seq_append_info            = v_seq_append_info
  member _.seq_generated_info         = v_seq_generated_info
  member _.seq_finally_info           = v_seq_finally_info
  member _.seq_trywith_info           = v_seq_trywith_info
  member _.seq_of_functions_info      = v_seq_of_functions_info
  member _.seq_map_info               = v_seq_map_info
  member _.seq_singleton_info         = v_seq_singleton_info
  member _.seq_empty_info             = v_seq_empty_info
  member _.sprintf_info               = v_sprintf_info
  member _.new_format_info            = v_new_format_info
  member _.unbox_info                 = v_unbox_info
  member _.get_generic_comparer_info  = v_get_generic_comparer_info
  member _.get_generic_er_equality_comparer_info = v_get_generic_er_equality_comparer_info
  member _.get_generic_per_equality_comparer_info = v_get_generic_per_equality_comparer_info
  member _.dispose_info               = v_dispose_info
  member _.getstring_info             = v_getstring_info
  member _.unbox_fast_info            = v_unbox_fast_info
  member _.istype_info                = v_istype_info
  member _.lazy_force_info            = v_lazy_force_info
  member _.lazy_create_info           = v_lazy_create_info
  member _.create_instance_info       = v_create_instance_info
  member _.create_event_info          = v_create_event_info
  member _.seq_to_list_info           = v_seq_to_list_info
  member _.seq_to_array_info          = v_seq_to_array_info

  member _.array_length_info          = v_array_length_info
  member _.array_get_info             = v_array_get_info
  member _.array2D_get_info           = v_array2D_get_info
  member _.array3D_get_info           = v_array3D_get_info
  member _.array4D_get_info           = v_array4D_get_info
  member _.array_set_info             = v_array_set_info
  member _.array2D_set_info           = v_array2D_set_info
  member _.array3D_set_info           = v_array3D_set_info
  member _.array4D_set_info           = v_array4D_set_info

  member val option_toNullable_info     = v_option_toNullable_info
  member val option_defaultValue_info     = v_option_defaultValue_info

  member _.deserialize_quoted_FSharp_20_plus_info       = v_deserialize_quoted_FSharp_20_plus_info
  member _.deserialize_quoted_FSharp_40_plus_info    = v_deserialize_quoted_FSharp_40_plus_info
  member _.call_with_witnesses_info = v_call_with_witnesses_info
  member _.cast_quotation_info        = v_cast_quotation_info
  member _.lift_value_info            = v_lift_value_info
  member _.lift_value_with_name_info            = v_lift_value_with_name_info
  member _.lift_value_with_defn_info            = v_lift_value_with_defn_info
  member _.query_source_as_enum_info            = v_query_source_as_enum_info
  member _.new_query_source_info            = v_new_query_source_info
  member _.query_builder_tcref            = v_query_builder_tcref
  member _.fail_init_info             = v_fail_init_info
  member _.fail_static_init_info           = v_fail_static_init_info
  member _.check_this_info            = v_check_this_info
  member _.quote_to_linq_lambda_info        = v_quote_to_linq_lambda_info


  member val cgh__stateMachine_vref = ValRefForIntrinsic v_cgh__stateMachine_info
  member val cgh__useResumableCode_vref = ValRefForIntrinsic v_cgh__useResumableCode_info
  member val cgh__debugPoint_vref = ValRefForIntrinsic v_cgh__debugPoint_info
  member val cgh__resumeAt_vref = ValRefForIntrinsic v_cgh__resumeAt_info
  member val cgh__resumableEntry_vref = ValRefForIntrinsic v_cgh__resumableEntry_info

  member val generic_hash_withc_tuple2_vref = ValRefForIntrinsic v_generic_hash_withc_tuple2_info
  member val generic_hash_withc_tuple3_vref = ValRefForIntrinsic v_generic_hash_withc_tuple3_info
  member val generic_hash_withc_tuple4_vref = ValRefForIntrinsic v_generic_hash_withc_tuple4_info
  member val generic_hash_withc_tuple5_vref = ValRefForIntrinsic v_generic_hash_withc_tuple5_info
  member val generic_equals_withc_tuple2_vref = ValRefForIntrinsic v_generic_equals_withc_tuple2_info
  member val generic_equals_withc_tuple3_vref = ValRefForIntrinsic v_generic_equals_withc_tuple3_info
  member val generic_equals_withc_tuple4_vref = ValRefForIntrinsic v_generic_equals_withc_tuple4_info
  member val generic_equals_withc_tuple5_vref = ValRefForIntrinsic v_generic_equals_withc_tuple5_info
  member val generic_compare_withc_tuple2_vref = ValRefForIntrinsic v_generic_compare_withc_tuple2_info
  member val generic_compare_withc_tuple3_vref = ValRefForIntrinsic v_generic_compare_withc_tuple3_info
  member val generic_compare_withc_tuple4_vref = ValRefForIntrinsic v_generic_compare_withc_tuple4_info
  member val generic_compare_withc_tuple5_vref = ValRefForIntrinsic v_generic_compare_withc_tuple5_info
  member val generic_equality_withc_outer_vref = ValRefForIntrinsic v_generic_equality_withc_outer_info


  member _.cons_ucref = v_cons_ucref
  member _.nil_ucref = v_nil_ucref

    // A list of types that are explicitly suppressed from the F# intellisense
    // Note that the suppression checks for the precise name of the type
    // so the lowercase versions are visible
  member _.suppressed_types = v_suppressed_types

  /// Are we assuming all code gen is for F# interactive, with no static linking
  member _.isInteractive=isInteractive

  member val compilationMode = compilationMode

  /// Indicates if we are generating witness arguments for SRTP constraints. Only done if the FSharp.Core
  /// supports witness arguments.
  member g.generateWitnesses =
      compilingFSharpCore ||
      ((ValRefForIntrinsic g.call_with_witnesses_info).TryDeref.IsSome && langVersion.SupportsFeature LanguageFeature.WitnessPassing)

  /// Indicates if we can use System.Array.Empty when emitting IL for empty array literals
  member val isArrayEmptyAvailable = v_Array_tcref.ILTyconRawMetadata.Methods.FindByName "Empty" |> List.isEmpty |> not

  member g.isSpliceOperator v =
    primValRefEq g.compilingFSharpCore g.fslibCcu v g.splice_expr_vref ||
    primValRefEq g.compilingFSharpCore g.fslibCcu v g.splice_raw_expr_vref

  member _.FindSysTyconRef path nm = findSysTyconRef path nm

  member _.TryFindSysTyconRef path nm = tryFindSysTyconRef path nm

  member _.FindSysILTypeRef nm = findSysILTypeRef nm

  member _.TryFindSysILTypeRef nm = tryFindSysILTypeRef nm

  member _.FindSysAttrib nm = findSysAttrib nm

  member _.TryFindSysAttrib nm = tryFindSysAttrib nm

  member _.AddGeneratedAttributes attrs = addGeneratedAttrs attrs

  member _.AddValGeneratedAttributes v = addValGeneratedAttrs v

  member _.AddMethodGeneratedAttributes mdef = addMethodGeneratedAttrs mdef

  member _.AddPropertyGeneratedAttributes mdef = addPropertyGeneratedAttrs mdef

  member _.AddFieldGeneratedAttributes mdef = addFieldGeneratedAttrs mdef

  member _.AddPropertyNeverAttributes mdef = addPropertyNeverAttrs mdef

  member _.AddFieldNeverAttributes mdef = addFieldNeverAttrs mdef

  member _.MkDebuggerTypeProxyAttribute ty = mkDebuggerTypeProxyAttribute ty

  member _.mkDebuggerDisplayAttribute s = mkILCustomAttribute (findSysILTypeRef tname_DebuggerDisplayAttribute, [ilg.typ_String], [ILAttribElem.String (Some s)], [])

  member _.DebuggerBrowsableNeverAttribute = debuggerBrowsableNeverAttribute

  member _.mkDebuggableAttributeV2(jitTracking, jitOptimizerDisabled) =
        let debuggingMode =
            0x3 (* Default ||| IgnoreSymbolStoreSequencePoints *) |||
            (if jitTracking then 1 else 0) |||
            (if jitOptimizerDisabled then 256 else 0)
        let tref_DebuggableAttribute_DebuggingModes = mkILTyRefInTyRef (tref_DebuggableAttribute, tname_DebuggableAttribute_DebuggingModes)
        mkILCustomAttribute
          (tref_DebuggableAttribute, [mkILNonGenericValueTy tref_DebuggableAttribute_DebuggingModes],
           (* See System.Diagnostics.DebuggableAttribute.DebuggingModes *)
           [ILAttribElem.Int32( debuggingMode )], [])

  member internal _.CompilerGlobalState = Some compilerGlobalState

  member _.CompilerGeneratedAttribute = compilerGeneratedAttribute

  member _.DebuggerNonUserCodeAttribute = debuggerNonUserCodeAttribute

  member _.HasTailCallAttrib (attribs: Attribs) =
    attribs
    |> List.exists (fun a -> a.TyconRef.CompiledRepresentationForNamedType.FullName = "Microsoft.FSharp.Core.TailCallAttribute")

  member _.MakeInternalsVisibleToAttribute(simpleAssemName) =
      mkILCustomAttribute (tref_InternalsVisibleToAttribute, [ilg.typ_String], [ILAttribElem.String (Some simpleAssemName)], [])

  /// Find an FSharp.Core LanguagePrimitives dynamic function that corresponds to a trait witness, e.g.
  /// AdditionDynamic for op_Addition.  Also work out the type instantiation of the dynamic function.
  member _.MakeBuiltInWitnessInfo (t: TraitConstraintInfo) =
      let memberName =
          let nm = t.MemberLogicalName
          let coreName =
              if nm.StartsWithOrdinal "op_" then nm[3..]
              elif nm = "get_Zero" then "GenericZero"
              elif nm = "get_One" then "GenericOne"
              else nm
          coreName + "Dynamic"

      let gtps, argTys, retTy, tinst =
          match memberName, t.CompiledObjectAndArgumentTypes, t.CompiledReturnType with
          | ("AdditionDynamic" | "MultiplyDynamic" | "SubtractionDynamic"| "DivisionDynamic" | "ModulusDynamic" | "CheckedAdditionDynamic" | "CheckedMultiplyDynamic" | "CheckedSubtractionDynamic" | "LeftShiftDynamic" | "RightShiftDynamic" | "BitwiseAndDynamic" | "BitwiseOrDynamic" | "ExclusiveOrDynamic" | "LessThanDynamic" | "GreaterThanDynamic" | "LessThanOrEqualDynamic" | "GreaterThanOrEqualDynamic" | "EqualityDynamic" | "InequalityDynamic"),
            [ arg0Ty; arg1Ty ],
            Some retTy ->
               [vara; varb; varc], [ varaTy; varbTy ], varcTy, [ arg0Ty; arg1Ty; retTy ]
          | ("UnaryNegationDynamic" | "CheckedUnaryNegationDynamic" | "LogicalNotDynamic" | "ExplicitDynamic" | "CheckedExplicitDynamic"),
            [ arg0Ty ],
            Some retTy ->
               [vara; varb ], [ varaTy ], varbTy, [ arg0Ty; retTy ]
          | "DivideByIntDynamic", [arg0Ty; _], _ ->
               [vara], [ varaTy; v_int32_ty ], varaTy, [ arg0Ty ]
          | ("GenericZeroDynamic" | "GenericOneDynamic"), [], Some retTy ->
               [vara], [ ], varaTy, [ retTy ]
          | _ -> failwithf "unknown builtin witness '%s'" memberName

      let vref = makeOtherIntrinsicValRef (fslib_MFLanguagePrimitives_nleref, memberName, None, None, gtps, (List.map List.singleton argTys, retTy))
      vref, tinst

  /// Find an FSharp.Core operator that corresponds to a trait witness
  member g.TryMakeOperatorAsBuiltInWitnessInfo isStringTy isArrayTy (t: TraitConstraintInfo) argExprs =

    match t.MemberLogicalName, t.CompiledObjectAndArgumentTypes, t.CompiledReturnType, argExprs with
    | "get_Sign", [aty], _, objExpr :: _ ->
        // Call Operators.sign
        let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "sign", None, Some "Sign", [vara], ([[varaTy]], v_int32_ty))
        let tyargs = [aty]
        Some (info, tyargs, [objExpr])
    | "Sqrt", [aty], Some bty, [_] ->
        // Call Operators.sqrt
        let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "sqrt", None, Some "Sqrt", [vara; varb], ([[varaTy]], varbTy))
        let tyargs = [aty; bty]
        Some (info, tyargs, argExprs)
    | "Pow", [aty;bty], _, [_;_] ->
        // Call Operators.(**)
        let info = v_exponentiation_info
        let tyargs = [aty;bty]
        Some (info, tyargs, argExprs)
    | "Atan2", [aty;_], Some bty, [_;_] ->
        // Call Operators.atan2
        let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "atan2", None, Some "Atan2", [vara; varb], ([[varaTy]; [varaTy]], varbTy))
        let tyargs = [aty;bty]
        Some (info, tyargs, argExprs)
    | "get_Zero", _, Some aty, ([] | [_]) ->
        // Call LanguagePrimitives.GenericZero
        let info = makeOtherIntrinsicValRef (fslib_MFLanguagePrimitives_nleref, "GenericZero", None, None, [vara], ([], varaTy))
        let tyargs = [aty]
        Some (info, tyargs, [])
    | "get_One", _, Some aty,  ([] | [_])  ->
        // Call LanguagePrimitives.GenericOne
        let info = makeOtherIntrinsicValRef (fslib_MFLanguagePrimitives_nleref, "GenericOne", None, None, [vara], ([], varaTy))
        let tyargs = [aty]
        Some (info, tyargs, [])
    | ("Abs" | "Sin" | "Cos" | "Tan" | "Sinh" | "Cosh" | "Tanh" | "Atan" | "Acos" | "Asin" | "Exp" | "Ceiling" | "Floor" | "Round" | "Truncate" | "Log10"| "Log"), [aty], _, [_] ->
        // Call corresponding Operators.*
        let nm = t.MemberLogicalName
        let lower = if nm = "Ceiling" then "ceil" else nm.ToLowerInvariant()
        let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, lower, None, Some nm, [vara], ([[varaTy]], varaTy))
        let tyargs = [aty]
        Some (info, tyargs, argExprs)
    | "get_Item", [arrTy; _], Some retTy, [_; _] when isArrayTy g arrTy ->
        Some (g.array_get_info, [retTy], argExprs)
    | "set_Item", [arrTy; _; elemTy], _, [_; _; _] when isArrayTy g arrTy ->
        Some (g.array_set_info, [elemTy], argExprs)
    | "get_Item", [stringTy; _; _], _, [_; _] when isStringTy g stringTy ->
        Some (g.getstring_info, [], argExprs)
    | "op_UnaryPlus", [aty], _, [_] ->
        // Call Operators.id
        let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "id", None, None, [vara], ([[varaTy]], varaTy))
        let tyargs = [aty]
        Some (info, tyargs, argExprs)
    | _ ->
        None

#if DEBUG
// This global is only used during debug output
let mutable global_g = None : TcGlobals option
#endif
